I am using: Rails 7 Bootstrap 5 Tom Select ^2.3.1
create:false should be the default. For some reason, create:true is the default.
When I add create:false, it doesn't register, and even if I try plugins: ['no_add'], that doesn't work either.
No matter what, when I inspect element, I see; create:true.
But I do not want users to be able to create new items from the dropdown.
Package.json:
{
"name": "app",
"private": "true",
"dependencies": {
"@hotwired/stimulus": "^3.2.1",
"@hotwired/turbo-rails": "^7.3.0",
"@popperjs/core": "^2.11.6",
"bootstrap": "^5.2.3",
"bootstrap-icons": "^1.10.3",
"esbuild": "^0.17.10",
"sass": "^1.58.3",
"tom-select": "^2.3.1"
},
"scripts": {
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets",
"build:css": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}
}
search_controller.js
import { Controller } from "@hotwired/stimulus"
import TomSelect from "tom-select"
// Connects to data-controller="search"
export default class extends Controller {
// static targets = ["input", "suggestions"];
connect() {
console.log("YES search controller working - connect method called", this.element);
new TomSelect(this.element, {
//Uncomment below and change create to true to allow user to add new entries from forms
//createOnBlur: true,
create: false,
plugins: ['no_add']
});
// document.addEventListener("click", (event) => { // <-- Corrected syntax
// if (!this.element.contains(event.target)) {
// this.hideSuggestions();
// }
// });
}
suggestions() {
console.log("Suggestion Function Running");
const query = this.inputTarget.value;
const url = this.element.dataset.suggestionsUrl;
clearTimeout(this.setTimeout)
this.timeout = setTimeout(()=> {
this.requestSuggestions(query,url);
}, 250);
}
requestSuggestions(query, url) {
if (query.length === 0) {
this.hideSuggestions();
return;
}
this.showSuggestions();
fetch (url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": document.querySelector("meta[name='csrf-token']").content
},
body: JSON.stringify ({query: query}),
}).then(response => {
response.text().then( html => {
document.body.insertAdjacentHTML("beforehand", "html");
})
})
}
hideSuggestions() {
if (!this.childWasClicked) {
this.suggestionsTarget.classList.add("hidden");
}
this.childWasClicked = false;
}
showSuggestions() {
this.suggestionsTarget.classList.remove("hidden");
}
}
Form code:
<h4>With Whom?</h4>
<%= form.select :contact_id, @contacts.map{|c| ["#{c.first_name} #{c.last_name}", c.id]},
{prompt: 'With whom did you have this Interaction?'},
class: 'autocomplete-form',
data: {
controller: 'search',
oldaction: 'keyup->search#suggestions',
suggestions_url: search_suggestions_path, search_target: "input"
} %>
<span>Need to <%= link_to "add a new contact", new_contact_path, target: "_blank" %>?</span>
</div>
This is what I see when I inspect element:
<div class="create active" data-selectable="" aria-selected="true">Add <strong>asdf</strong>…</div>
Here is a phot of the inspect element:
Hmmm taking a wild guess here but it looks like your newly typed javascript code is not being run, meaning your rails server is still running the old javascript code. Because the js code you have written is correct and should render the create:false element you are seeking.
Look in the app/assets folder for the compiled js code. Does it match the JS code that you just wrote? If not, it means you have to compile your js files into the app/assets folder again. This ensures that rails s
can serve these compiled assets, meaning what you see in the browser is the reflection of what you actually just wrote instead of the old assets.