Rails 7 JavaScript dosya yüklenme sırası nasıl ayarlanabilir? Ayrıca kendi js dosyalarımızı nereye yazmalıyız?

Herkese selamlar. Rails 7 ile geliştirmeye başladığım uygulama için semantic-ui css framework eklemek istiyorum. import map dosyama aşağıdaki kodları ekledim.

pin "jquery", to: "https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js", preload: true
pin "semantic-ui", to: "https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.js", preload: true

Semantic.css dosyamı app/assets/stylesheets/semantic.css olarak ekledim.

Many_to_many ilişkiyi formdan girebilmek için erb dosyama searchable multiple selection dropdown ekledim.

<%= form.collection_select :subject_ids, Subject.order( :name), :id, :to_s, {prompt: true},  {class: "ui fluid multiple search selection dropdown", multiple: "", size: 10} %>

Dropdown selectin sorunsuz çalışması için aşağıdaki kodu eklemem gerek.

$('.ui.dropdown')
  .dropdown()
;

app/javascript/application.js içini aşağıdaki gibi düzenledim.

import "@hotwired/turbo-rails"
import "controllers"
import "jquery"
import "semantic-ui"

$('.ui.dropdown')
  .dropdown()
;

Bu noktada semantic-ui dropdown new request’te sorunsuz çalışıyor. Fakat edit request gönderdiğimde mevcut seçenekler seçili geliyor ama arayüz html5 arayüzü olarak geliyor. Sayfayı yenileyince sorun düzeliyor.

Burada rails arkaplanda farklı birşeyler yaptığı için mi application.js. ilk yüklemede devreye girmiyor? Sorunu nasıl çözebilirim?

Ayrıca js yazacağımız doğru yer neresi ve nasıl olmalı konusunu ben henüz anlamadım. Bilen var mı acaba? Yahut bir rehber bilen varsa bende bakabilirim.

Selam.

Yenileyince düzelmesi bana sorunun turbo ile ilişkili olduğu hissini uyandırdı. Form post edildikten sonra dönen cevaba tarayıcının developer tools panelinin network sekmesinden bir bak. Eğer her şey normal görünüyorsa turbo olmadan bir dene bakalım.

Selamlar,
Bu sorun tamamen semantic’in onReady event’ını dinleyerek şekillendirmeleri yapması. Turbo ile kullanırken turbo’nun eventlarını handle ederek tekrardan dropdown methodunu execute etmek gerekli.

document.addEventListener("turbo:load", function(event) { $('.ui.dropdown').dropdown(); }, false)

şeklinde.

2 Likes

Her ikinize de teşekkürler. Sorun @m_dilmac 'ın bahsettiği sebepten ötürüymüş. Çözüldü çok teşekkürler. :wave: :slightly_smiling_face:

Merhaba,

Buradaki @m_dilmac çözümüne ilaveten eklemek istediğim bir husus daha var;

Eğer dropdown sadece bu formda bulunan collection combobox’ta aktive olacak ise, bu combobox’ı bir Stimulus Controller’a bağlamak ve controller sayfaya connect olduktan sonra combobox’a uygulaman daha iyi bir yaklaşım olacaktır.

Bu tarz kodu Application.js’e yazıp her sayafada ui.dropdown’u arayan kodun çalışmasına engel olmak ve sadece gerektiğinde Stimulus ile çağırmanı tavsiye ederim.

Öneri A

<%= form.collection_select :subject_ids, 
    Subject.order( :name), :id, :to_s, {prompt: true}, 
   {data-controller: "dropdown" class: "ui fluid multiple search selection dropdown", multiple: "", size: 10} 
%>
// dropdown_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  connect() {
    this.element.dropdown();
  }
}

Yukarıdaki kodun Semantic UI’daki Dropdown’ın jQuery bağımlılığını kestiremediğim için çalışmama olasılığına karşın bir alternatif öneri de aşağıdaki gibi olabilir;

Öneri B
Bu noktada Semantic UI’da uygulama işleminin mutlaka jQuery ile yapılması gerekiyorsa o zaman Stimulus Controller’ı şöyle değiştirebilirsin.

// dropdown_controller.js
import "jquery"
import "semantic-ui"
import { Controller } from "stimulus"

export default class extends Controller {
  connect() {
    $(this.element).dropdown();
  }
}

Kolaylıklar.

3 Likes

Benim için çok kıymetli bir bilgi. Teşekkür ederim ilk fırsatımda uygulamaya çalışacağım. Bende stimulus kontroller olayını anlamaya çalışıyordum. İyi oldu. :slight_smile: :clap: :clap:

1 Like

Merhaba çözümü projeme eklerken yukarıdaki kullanım erb render ederken hata veriyor.

Şöyle alttaki gibi birşey ekledim.

<%= form.label :subject_id, style: "display: block" %>
    <%= form.collection_select :subject_ids, Subject.order( :name), :id, :to_s, {prompt: true}, 
    {class: "ui fluid multiple search selection dropdown", multiple: "", size: 10} %>
    <div data-controller="dropdown"></div>

Sonra alttaki gibi controller ekledim çalıştı.

// dropdown_controller.js
import "jquery"
import "semantic-ui"
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {   
    $('.ui.dropdown').dropdown();
  }
}

Ayrıca ilk denemede appliaction.js içerisine yazdığım kod form.errors çağırıldığında javascriptin ikinci kez yüklenmemesi problemine sebep olmuştu. Stimulus controller yaklaşımı bu sorunu çözdü. Teşekkür ederim.

Örneği kontrol etmeden aklımdan yazmıştım bu sebeple syntax error oluşturmuş olabilirim :slight_smile:

<%= form.collection_select :subject_ids, 
    Subject.order( :name), :id, :to_s, {prompt: true}, 
   { data: { controller: "dropdown" }, class: "ui fluid multiple search selection dropdown", multiple: "", size: 10} 
%>

Doğru kullanım: data: { controller: "dropdown" } veya data_controller: "dropdown"

Yukarıdaki şekilde düzeltirsen çalışması yüksek ihtimal. Çıktı olarak aşağıdaki gibi bir HTML üretmesi gerekli;

<select data-controller="dropdown" 
  class="ui fluid multiple search selection dropdown" 
  multiple="multiple" size="10" name="resource[subject_ids][]" 
  id="resource_subject_ids">
  <option value="">Please select</option>
</select>

Bir kontrol edip geri bildirim verirsen sevinirim.

Kolaylıklar.

1 Like

Tamamdır bu sefer oldu. :+1:
Aslında benim formda 6 ayrı dropdown var. Sadece birisine controller atamak hepsini çalıştırıyor. Bu durumda kod okunabilirliği pek iyi olmuyor açıkçası. Bireysel proje olduğu için şuan sıkıntı yok. :slight_smile:

1 Like