Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autocomplete Form with Specific Terms

I'm working with a web application that is developed with the Phoenix Framework (written in Elixir).

I've got a form field that currently looks like this:

<div class="form-group">
  <%= select f, :category_id, @categories, class: "form-control" %>
  <%= error_tag f, :category_id %>
</div>

This allows users to select a category from a drop down list (which is okay); however, what I'd like users to see is a standard text field that will autocomplete the string that the enter with categories from my database as they start typing it.

Very similar functionality as the Tags field that we use when posting a question on Stack Overflow.

What would that be the best way to do this with a Phoenix application? I've tried using jQuery Autocomplete; however, I'd like a more 'light weight' solution (that doesn't require jQuery).

Any ideas are greatly appreciated. Thank you for your time.

like image 466
Andrew Hendrie Avatar asked Apr 26 '16 23:04

Andrew Hendrie


2 Answers

The only solution I can think of not involving JavaScript at all is a datalist. It's a great new HTML5 element that does exactly what you need, but its browser support isn't great (update 2021: support is much better nowadays).

If you are looking to avoid JQuery, but are still OK with using some other JS widget, you should take a look at Awesomplete - "an ultra lightweight, customizable, simple autocomplete widget with zero dependencies". If you include the minimal JS and CSS files they sum up to only about 8kb. It's also ridiculously easy to implement:

<input class="awesomplete"
       data-list="category1, category2, category3, category4, category5" />

And it can even attach to your current select box (you'll have to hide it though):

<style>
  #mylist { display: none; }
</style>

<div class="form-group">
  <input class="awesomplete" list="mylist" />
  <%= select f, :category_id, @categories, class: "form-control", id: "mylist" %>
  <%= error_tag f, :category_id %>
</div>

Of course don't forget to add the JS and CSS files in your head:

<link rel="stylesheet" href="awesomplete.css" />
<script src="awesomplete.min.js" async></script>
like image 156
Shovalt Avatar answered Oct 02 '22 13:10

Shovalt


Pure vanilla javascript solution compatible with every framework that supports javascript

  1. In this approach a text box is listened for keyup and each time event occurs input text is matched with predefined set of input and if found is added to a underlying UL tag as li elements
  2. Here the css for li take from what rendered on chrome for text box it can be customized for your liking
  3. And regarding the taking of values or tags from within database part is also not a problem you can use ajax to get values by passing input as parameter to server side and returning the matched tags and appending it

    // variables
    var input = document.querySelector('input');
    var people = ['john doe', 'maria', 'paul', 'george', 'jimmy','Andrew','Hendrie'];
    var results;
    
    // functions
    function autocomplete(val) {
      var people_return = [];
    
      for (i = 0; i < people.length; i++) {
        if (val === people[i].slice(0, val.length)) {
          people_return.push(people[i]);
        }
      }
    
      return people_return;
    }
    
    // events
    input.onkeyup = function(e) {
      input_val = this.value; // updates the variable on each ocurrence
    
      if (input_val.length > 0) {
        var people_to_show = [];
    
        autocomplete_results = document.getElementById("autocomplete-results");
        autocomplete_results.innerHTML = '';
        people_to_show = autocomplete(input_val);
        
        for (i = 0; i < people_to_show.length; i++) {
          autocomplete_results.innerHTML += '<li>' + people_to_show[i] + '</li>';
    
        }
        autocomplete_results.style.display = 'block';
      } else {
        people_to_show = [];
        autocomplete_results.innerHTML = '';
      }
    }
ul{
padding:0;
margin:0;  
}
li{
  max-width:169px;

      padding: 1px 0px;
list-style:none;
      -webkit-appearance: textfield;
    background-color: white;
    border-image-source: initial;
    border-image-slice: initial;
    border-image-width: initial;
    border-image-outset: initial;
    border-image-repeat: initial;
    -webkit-rtl-ordering: logical;
    -webkit-user-select: text;
    cursor: auto;
    padding: 1px;
    border-width: 2px;
    border-style: inset;
    border-color: initial
          text-rendering: auto;
    color: initial;
    letter-spacing: normal;
    word-spacing: normal;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;

    text-align: start;
    margin: 0em 0em 0em 0em;
    font: 13.3333px Arial;
}
<div id="autocomplete-container">  
  <input type="text" autofocus="true" name="autofocus sample" placeholder="search people" id="autocomplete-input"/>
  <ul id="autocomplete-results">
  </ul>
</div>

OR

Simplest solution for html5 supporting browsers would be data-list

<input list="browsers">

<datalist id="browsers">
  <option value="Internet Explorer">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Opera">
  <option value="Safari">
</datalist>

http://www.w3schools.com/tags/tag_datalist.asp

EDIT 1

With Added Navigation I forgot to change the textbox change with respect to navigation will add it soon

like image 21
codefreaK Avatar answered Oct 02 '22 13:10

codefreaK