Skip to content

Instantly share code, notes, and snippets.

@leastbad
Last active January 10, 2022 09:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save leastbad/bbc4a84c7c1c870b246db48b7641209e to your computer and use it in GitHub Desktop.
Save leastbad/bbc4a84c7c1c870b246db48b7641209e to your computer and use it in GitHub Desktop.
slim-select Stimulus controller w/ Reflex callback
class UsersReflex < ApplicationReflex
def search(name)
users = User.where("name LIKE :prefix", prefix: "#{name}%")
result = users.map { |user| { text: user.name, value: user.id }}
cable_ready.dispatch_event(name: "data", detail: {options: result}).broadcast
morph :nothing
end
end
<%# no, you shouldn't do AR queries in your view %>
<select id="user" class="w-100" name="user" data-controller="select" data-select-reflex-value="Users#search">
<% User.all.each do |user| %>
<option value="<%= user.id %>"><%= user.name %></option>
<% end %>
</select>
"dependencies": {
"slim-select": "https://github.com/leastbad/slim-select",
"stimulus": "^2.0.0"
}
import ApplicationController from './application_controller'
import SlimSelect from 'slim-select'
export default class extends ApplicationController {
static values = {
limit: Number,
placeholder: String,
searchText: String,
searchingText: String,
reflex: String
}
connect () {
super.connect()
const closeOnSelect = this.single
const allowDeselect = !this.element.required
this.select = new SlimSelect({
select: this.element,
closeOnSelect,
allowDeselect,
limit: this.limitValue,
placeholder: this.hasPlaceholderValue
? this.placeholderValue
: 'Select Value',
searchText: this.hasSearchTextValue ? this.searchTextValue : 'No Results',
searchingText: this.hasSearchingTextValue
? this.searchingTextValue
: 'Searching...',
ajax: this.hasReflexValue ? this.search : () => {},
onChange: this.onChange
})
if (this.hasReflexValue) document.addEventListener('data', this.results)
}
search = (search, callback) =>
this.stimulate(this.reflexValue, search).then(() => callback(false))
results = event => this.select.setData(event.detail.options)
onChange = () => {
if (!this.select.data.searchValue) return
if (this.select.selected() === undefined)
this.stimulate(this.reflexValue, '')
}
get single () {
return !this.element.multiple
}
get multi () {
return this.element.multiple
}
disconnect () {
this.select.destroy()
if (this.hasReflexValue) document.removeEventListener('data', this.results)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment