Hello fellow developers,
From last 2 days I am trying to find a way how to pass a variable between Stimulus and Rails views, and probably because of lack of experience in Rails I can’t get my head around this problem.
I have a slick gallery, that includes photos of the car ( left hand side ), and in the right column I have a select input field ( first one with the Shwarz inside ). What I want to do is the following:
- Change a color
- Update loop that renders the photos
- Render the photos
- Reload slick gallery
So far I have the following progress - gallery:
<div data-target="colour.gallery" class="slick-slider col-12">
<% Dir.glob('app/assets/images/car-gallery/color-picker/black/*').map do |path| %> <-- I want to be able to update the BLACK part of the DIR
<%= image_tag("car-gallery/color-picker/black/#{File.basename(path)}", class: 'd-block w-100') %> <-- same here obviously
<% end.reduce(&:+) %>
<% Dir.glob('app/assets/images/car-gallery/interiors/*').map do |path| %>
<%= image_tag("car-gallery/interiors/#{File.basename(path)}", class: 'd-block w-100') %>
<% end.reduce(&:+) %>
</div>
<div class="col-12 mb-1">
<p class="mb-0 text-size-sm">Fahrzeug enthält Sonderausstattung.</p>
</div>
<div data-target="colour.thumbnails" class="slick-navigation col-12">
<% Dir.glob('app/assets/images/car-gallery/color-picker/black/*').map do |path| %>
<div class="slick-navigation-item">
<%= image_tag("car-gallery/color-picker/black/#{File.basename(path)}", class: 'd-block w-100') %>
</div>
<% end.reduce(&:+) %>
<% Dir.glob('app/assets/images/car-gallery/interiors/*').map do |path| %>
<div class="slick-navigation-item">
<%= image_tag("car-gallery/interiors/#{File.basename(path)}", class: 'd-block w-100') %>
</div>
<% end.reduce(&:+) %>
</div>
Stimulus controller:
import { Controller } from 'stimulus'
export default class extends Controller {
static targets = ['trigger', 'gallery', 'thumbnails']
connect() {
console.log(this.value())
console.log(this.galleryTarget)
console.log(this.thumbnailsTarget)
console.log(this.triggerTarget)
}
value() {
const colours = {
'schwarz': 'black',
'weiß': 'white',
'grau': 'grey',
'rot': 'red'
}
const selected = colours[$(this.triggerTarget).val().toLowerCase()]
console.log(selected)
return selected === undefined ? 'black' : selected
}
}
How is it possible to pass a value that is returned inside value() method and pass it to the loop, and re render that part?
Of course there is a great possibility that I am overthinking the problem… I can always just add plain image_tags with data attributes. However it doesn’t feel as a very DRY solution, especially that In order to make a gallery in Slick.js I need to synchronise 2 carousels, with the same content inside, which creates the need of adding the same content twice.