Last active
October 16, 2024 20:39
-
-
Save tabishiqbal/dc78239aa5b81b257db0633ace75ecc0 to your computer and use it in GitHub Desktop.
Ruby on Rails Tom-Select Example with Stimulus controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%= form_with(model: team) do |form| %> | |
<div> | |
<%= form.label :name %> | |
<%= form.text_field :name, class: "input" %> | |
</div> | |
<div> | |
<%= f.select :user_id, {}, {placeholder: "Select user"}, {class: "w-full", data: { controller: "select", select_url_value: users_path }} %> | |
</div> | |
<%= form.submit "Save product", class: "btn-primary" %> | |
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app/javascript/controllers/select_controller.js | |
import { Controller } from "stimulus"; | |
import TomSelect from "tom-select"; | |
export default class extends Controller { | |
// Define static value to fetch the URL from HTML data attributes. | |
static values = { url: String }; | |
// Triggered when the Stimulus controller is connected to the DOM. | |
connect() { | |
this.initializeTomSelect(); | |
} | |
// Triggered when the Stimulus controller is removed from the DOM. | |
disconnect() { | |
this.destroyTomSelect(); | |
} | |
// Initialize the TomSelect dropdown with the desired configurations. | |
initializeTomSelect() { | |
// Return early if no element is associated with the controller. | |
if (!this.element) return; | |
// Construct URL for fetching data which comes from the static value. | |
// https://tom-select.js.org/examples/remote/ | |
const url = `${this.urlValue}.json`; | |
// Fetch data for the dropdown. | |
const fetchData = (search, callback) => { | |
fetch(url) | |
.then(response => response.json()) // Convert response to JSON. | |
.then(data => callback(data)) // Send data to TomSelect. | |
.catch(() => callback()); // Handle any errors. | |
}; | |
// Define custom rendering for dropdown options. | |
// see: https://tom-select.js.org/examples/customization/ | |
const renderOption = (data, escape) => { | |
return ` | |
<div> | |
<span class="block">${escape(data.name)}</span> | |
<span class="text-gray-400">${escape(data.email)}</span> | |
</div> | |
`; | |
}; | |
// Create a new TomSelect instance with the specified configuration. | |
// see: https://tom-select.js.org/docs/ | |
// value, label, search, placeholder, etc can all be passed as static values instead of hard-coded. | |
this.select = new TomSelect(this.element, { | |
plugins: ['remove_button'], | |
valueField: 'id', | |
labelField: 'name', | |
searchField: ['name', 'email'], | |
maxItems: 1, | |
selectOnTab: true, | |
placeholder: "Select user", | |
closeAfterSelect: true, | |
hidePlaceholder: false, | |
preload: true, | |
create: false, | |
openOnFocus: true, | |
highlight: true, | |
sortField: { field: "name", direction: "asc" }, | |
load: fetchData, | |
render: { | |
option: renderOption | |
} | |
}); | |
} | |
// Cleanup: Destroy the TomSelect instance when the controller is disconnected. | |
destroyTomSelect() { | |
if (this.select) { | |
this.select.destroy(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UsersController < ApplicationController | |
def index | |
# ... (other code) | |
respond_to do |format| | |
# ... (other formats) | |
format.json { render json: format_users_as_json(@users) } | |
end | |
end | |
private | |
def format_users_as_json(users) | |
users.map do |user| | |
{ | |
name: user.name, | |
id: user.id, | |
email: user.email | |
} | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment