DollarChills
DollarChills

Reputation: 1086

Rails autocomplete with javascript

I'm using Awesomplete to help with autocompletion of a list of towns in a rails 6 application. Everything is working as it should, but once a town is selected it shows the value in the put field instead of the name of the town. Is it possible to show the name once a town is selected but still search by the value?

Form

<%= text_field_tag(:location, value = nil, html_options = {class: 'form-control', id: 'myLocation', placeholder: 'Start typing a town name'}) %>
<%= submit_tag 'Search' %>

Javascript

var input = document.getElementById("myLocation");
    new Awesomplete(input, {
        list: [['Town 1',100],['Town 2',200]...]
    });

Once search is implemented it takes the '100' or '200' value from the array and passes it into the location params.

Controller

data = HTTParty.get("https://www.urlofapi.com/params[:location]}")
@ddcalc = JSON.parse(data.body)

Upvotes: 3

Views: 473

Answers (2)

3limin4t0r
3limin4t0r

Reputation: 21110

The documentation has an example for this under the "Basic Usage" section:

// Show label and insert label into the input:
new Awesomplete(input, {
    list: [
        { label: "Belarus", value: "BY" },
        { label: "China", value: "CN" },
        { label: "United States", value: "US" }
    ],
    // insert label instead of value into the input.
    replace: function(suggestion) {
        this.input.value = suggestion.label;
    }
});

Applying this for your given example would result in:

var input = document.getElementById("myLocation");
new Awesomplete(input, {
    list: [['Town 1', 100], ['Town 2', 200]],
    replace: function (suggestion) {
        this.input.value = suggestion.label;
    }
});
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.js"></script>

<input id="myLocation"    type="text" />

This might result in the label being submitted rather than the value. However you could opt for a solution where you set a separate (hidden) input that is updated with the value belonging to the label.

const locations = { "Town 1": 100, "Town 2": 200 },
      locationLabel = document.getElementById("locationLabel"),
      locationValue = document.getElementById("locationValue"),
      setLocationValue = function (event) {
        const label = event.target.value;
        locationValue.value = locations.hasOwnProperty(label)
                            ? locations[label]
                            : "";
      };

new Awesomplete(locationLabel, { list: Object.keys(locations) });
locationLabel.addEventListener("input", setLocationValue);
locationLabel.addEventListener("awesomplete-selectcomplete", setLocationValue);
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.js"></script>

<input id="locationLabel" type="text" />
<input id="locationValue" type="text" placeholder="hide this input" />

Upvotes: 0

errakeshpd
errakeshpd

Reputation: 2552

You need to explicitly replace the 'this.input.value' as below

new Awesomplete(input, {
  list: [
    { label: "Town 1", value: "100" },
    { label: "Town 2", value: "200" }
  ],
  replace: function(suggestion) {
    this.input.value = suggestion.label; // You can assign label or value as per your need
  }
});

If you want to search with 100, 200 and want to display Town 1 in textbox then

new Awesomplete(input, {
  list: [
   { label: "100", value: "Town 1" },
   { label: "200", value: "Town 2" }
  ],
  replace: function(suggestion) {
    this.input.value = suggestion.value; // You can assign label or value as per your need
  }
 });

if this params[:location] is needed id i am suggesting you to use a hidden field to keep suggestion.label

Upvotes: 1

Related Questions