It comes with an AwesompleteUtil javascript library which adds the following features:
- Dynamic remote data loading; based on what is typed-in it performs an ajax lookup.
- Allow HTML markup in the shown items. Show value with description. Optionally search in the description text.
- Show when there is an exact match.
- Show when there isn't a match.
- When there is an exact match show related data (supplied in the remote data) in other parts of the page.
- Select the highlighted item when the tab key is used.
Examples
EEx
<%= copy_to_id(:user, :name1, "avatar_url", "#awe-avatar-img") %>
<%= awesomplete(
:user,
:name1,
[ # input_text options
class: "form-control",
autocomplete: "off"
],
%{
url: "https://api.github.com/search/users?q=",
urlEnd: " in:login type:user&per_page=30",
minChars: 3,
maxItems: 10,
limit: 30,
value: "login",
filter: "AwesompleteUtil.filterStartsWith",
item: "AwesompleteUtil.itemStartsWith"
}
) %>
The maxItems
parameter indicates that maximum 10 suggestions must be shown in the dropdown.
The per_page
parameter in the url tells the server to return maximum 30 suggestions per call.
The limit
parameter informs the AwesompleteUtil component that normally 30 results can be expected. If there are less than 30 results, any additional characters in the search phrase won't need a new server call, because all the matching suggestions are already retrieved.
The client-side suggestions filter
must be made consistent with the search functionality of the REST API. In this case, the server will only return usernames that start with the entered text, and the client-side filter should work in the same way.
The item
parameter is configured to highlight only matching text at the beginning of the suggestions, to clearly indicate why these suggestions are shown.
The iTunes service doesn't support wildcards but others (like Elasticsearch) do. Assuming that the user
is completing the last word while typing, you could add a * wildcard at the end of the search url with the
urlEnd: '*'
configuration to search the last word starting with the typed letters.
EEx
<%= awesomplete(
:user,
:artist1,
[ # input_text options
class: "form-control"
],
%{
url: "https://itunes.apple.com/search?entity=musicArtist&attribute=artistTerm&media=music&limit=15&country=gb&sort=artistTerm&term=",
limit: -1,
debounce: 300,
filter: "AwesompleteUtil.filterWords", # javascript functions must be double quoted
item: "AwesompleteUtil.itemWords",
value: "artistName"
}
) %>
EEx
<%= copy_to_id(:user, :track1, "collectionName", "#awe-track-album") %>
<%= copy_to_id(:user, :track1, "artistName", "#awe-track-artists") %>
<%= copy_to_id(:user, :track1, "artworkUrl100", "#awe-track-album-img") %>
<%= awesomplete(
:user,
:track1,
[ # input_text options
class: "form-control",
autocomplete: "off"
],
%{
url: "https://itunes.apple.com/search?entity=song&attribute=songTerm&media=music&limit=10&country=gb&sort=songTerm&term=",
limit: -1,
debounce: 300,
maxItems: 10,
minChars: 4,
value: "trackName",
descr: "collectionName",
filter: "AwesompleteUtil.filterWords",
item: "AwesompleteUtil.itemWords"
}
) %>
Unfortunetly we cannot instruct to iTunes to sort on song title length.
If you search for songs with only one or two words, it might be that the desired song is not in the first
10 shown results.
HTML
<span class="input-group-btn">
<button class="dropdown-btn" id="awe_btn_user_combocountry" type="button" tabindex="-1">
<span class="caron">▼</span>
</button>
</span>
EEx
<%= awesomplete(
:user,
:combocountry,
[ # input_text options
class: "form-control"
],
%{
url: "https://restcountries.com/v2/all",
loadall: true,
prepop: true,
minChars: 1,
maxItems: 8,
value: "name",
combobox: true
}
) %>
The prepop:true makes sure that the countries are loaded during page load.
The combobox:true will open/close the list when the button is pushed, assuming the id of the button is 'awe_btn_' + id of input-text. Instead of true/false you can also supply the id of the button with the combobox property.
EEx
<%= awesomplete(
:user,
:host1,
[
class: "form-control"
],
%{
url: "/js/host.json",
loadall: true,
filter: "Awesomplete.FILTER_STARTSWITH",
value: "value",
descr: "label",
data: "function (data, input) { var before = (input.slice(0, input.indexOf('@')) + '@').trim(); return {label: before + data.label, value: before + data.value}; }"
}
) %>
Javascript
EEx
<%= awesomplete(
:user,
:country_iso,
[
class: "form-control",
autocomplete: "off"
],
%{
url: "https://restcountries.com/v2/alpha/",
value: "alpha3Code",
limit: 0,
minChars: 3,
maxItems: 0,
filter: "Awesomplete.FILTER_STARTSWITH",
ajax: ajax404
}
) %>
A limit:1 tells that not more than 1 result is expected, so the json service doesn't have to return an array.
With limit:0 it will always re-query if more characters are typed.
EEx
<%= text_input(:user, :color, [value: "purple" class: "form-control"]) %>
<div><span id="awe-color-result"></span> ↲</div>
<%= copy_to_id(:user, :color, "label", "#awe-color-result") %>
<%= awesomplete_script(
:user,
:color,
%{
minChars: 1,
filter: "AwesompleteUtil.filterContains",
list: "[
{ label: \"<b style='color:black'>black</b>\", value: 'black' },
{ label: \"<b style='color:blue'>blue</b>\", value: 'blue' },
{ label: \"<b style='color:brown'>brown</b>\", value: 'brown' },
{ label: \"<b style='color:green'>green</b>\", value: 'green' },
{ label: \"<b style='color:orange'>orange</b>\", value: 'orange'},
{ label: \"<b style='color:pink'>pink</b>\", value: 'pink' },
{ label: \"<b style='color:purple'>purple</b>\", value: 'purple'},
{ label: \"<b style='color:red'>red</b>\", value: 'red' },
{ label: \"<b style='color:yellow'>yellow</b>\", value: 'yellow'}
]"
}
) %>
Notice the prepop property and the startCopy function call. The initial/autofilled value of input-control triggers the copy action, and the label is copied to the span-tag with id 'awe-color-result' during page load. The order of the HTML elements and the inline script is important here. The startCopy function must be called before the startAwesomplete function, because the latter can immediately fire the 'awesomplete-prepop' event which should be handled by the former.
The startCopy inline script should preferable be placed after the HTML element which is the target. If you do, it only has to lookup the target element once, but if you don't do this it will lookup the target element with each event.
If you use remote data loading and combine prepop:true with loadall:true the remote call will happen during page load. If prepop:false, the loadall will be done lazely, e.g. if the user makes changes and the input size >= minChars.
EEx
<%= copy_to_field(:user, :country, "capital", :user, :capital) %>
<%= copy_to_field(:user, :capital, "name", :user, :country) %>
<%= label(:user, :country, "Country", class: "control-label col-sm-2") %>
<div class="col-sm-4">
<%= awesomplete(:user, :country,
[class: "form-control"
],
[
assign: true,
minChars: 1,
maxItems: 7,
value: "name"
]) %>
</div>
<%= label(:user, :capital, "Capital", class: "control-label col-sm-2") %>
<div class="col-sm-4">
<%= awesomplete(:user, :capital,
[class: "form-control"
],
[
assign: true,
minChars: 1,
maxItems: 7,
value: "capital"
]) %>
</div>
Javascript
EEx
<%= awesomplete(
:user,
:seafood,
[
class: "form-control",
"data-list": "Anchovies, Cajun Prawn, Crayfish, Lobster, Oysters, Prawns, Salmon, Shrimps, Smoked Salmon, Squid, Tuna, Whitebait"
],
%{
minChars: 1,
multiple: ",;"
}
) %>
EEx
<%= awesomplete(
:user,
:multimail,
[
class: "form-control"
],
%{
url: "https://raw.githubusercontent.com/kentcdodds/starwars-names/main/src/starwars-names.json",
convertResponse: "names2contacts",
loadall : true,
minChars: 1,
maxItems: 7,
multiple: ";,",
value: "value",
label: "name",
descr: "email",
item: "AwesompleteUtil.itemMarkAll"
}
) %>
In this example the 'value' field contains both name (label) and email address (descr).
By default the description is not highlighted. The itemMarkAll function above
highlights all matching text in the suggestion list, including the description.
Try for example to search on '@starwars.com' to see what it highlights with or without this function.
Javascript
EEx
<%= awesomplete(
:user,
:seafood2,
[
class: "form-control",
"data-list": "Anchovies, Cajun Prawn, Crayfish, Lobster, Oysters, Prawns, Salmon, Shrimps, Smoked Salmon, Squid, Tuna, Whitebait"
],
%{
minChars: 1"
}
) %>
Javascript