Stimulus ile Panoya Kopyalama
Bu yazıda Stimulus’un temel bazı özelliklerinden bahsederken, Stimulus ile Rails uygulamasına ‘Panoya Kopyalama’ özelliğinin nasıl eklenebileceğinden bahsedilecek.
Örnek olarak view’ımızda şarkı sözleri olsun.
Bu HTML kodunun çıktısı şu şekilde olacaktır.
Amacımız kullanıcı kopyalama ikonuna tıklandığında şarkı sözlerinin kullanıcının panosuna (clipboard’a) kopyalanmasını sağlamak.
İkon’a tıklandığında şarkı sözlerinin panoya kopyalanmasını sağlamak için gerekli adımlar şu şekilde sıralanabilir:
- Stimulus’ta
clipboard_controller.js
oluşturulmalı. - Kopyalanacak içeriğin, oluşturulan controllera referans (target) edilmesi sağlanmalı.
- İkon’un
data attribute
‘una ikona tıklandığında çalışması üzere,data-action
attribute’undacopy
adında bir JS methodu tanımlanmalı. - Kopyalanılacak içeriğin (şarkı sözleri)
clipboard controller
‘da referans (target) edilmesi sağlanmalı. - Kopyalama işleminin başarılı olduğunu kullanıcıya bildirebilmek (feedback) amacıyla; ikonun konumunda bir süreliğine ‘Kopyalandı.’ yazmalı ve ikon eski haline dönmeli.
HTML tarafında gerekli değişiklikleri uyguladığımızda, kod şu şekilde görünecektir.
- Tüm içeriği saran div (wrapper),
data-controller
özelliği ileclipboard_controller.js
‘e bağlanması sağlandı. Böylece Stimulus controller’ın scope’u tanımlanmış oldu1. - İkon buton ile wrap edildi, Butona tıklandığında JS controller’da oluşturulacak
copy
methodunun çalışmasını sağlandı. - Butonun varsayılan davranışı tıklama (click) olduğu için, yalnızca action’i yazmamız yetecektir. jQuery’deki gibi
click->clipboard#copy
şeklinde bir syntax’a gerek duyulmamaktadır2. - 2 numaralı hedefi (şarkı sözlerini controller’a target olarak tanımlamak) gerçekleştirmek için şarkı sozlerinin oldugu div’e
text-container
target’i verildi. - İkonu wrap eden butona
clipboard-button
target’i tanimlanarak 5 numaralı hedefi gerçeklestirmek için target hazırlandı. - 5 numaralı hedefini gerçekleştirmek için, clipboard controller’a
notify-message-value
gönderildi, bu sayede lokalize edilmiş bir mesaj ile ‘Kopyalamanın başarılı olduğunu’ kullanıcıya bildirilebilecek.
Şimdi, Stimulus tarafında oluşacak targetlarımız ve methodlarımız belli, bunları oluşturabiliriz.
Target’lar temelde querySelector’ler ile çalışan, ilgili tanımlı elementleri bulup erişmemizi, üzerinde işlem yapmamızı kolaylaştıran bir yöntemdir. Stimulus, controller’ın scope’undaki elemanları queryElement
methodu aracılığıyla data attributelar üzerinden bulur ve kullanabilmemize olanak sağlamaktadır3.
// targets
static targets = ['textContainer', 'clipboardButton']
Value tanımlaması esnasında value’nun tipini ve varsayılan değerini vererek daha tutarlı bir çalışma şekli sağlayabiliriz. Örneğin, lokalizasyon tanımlanmadıysa varsayılan olarak İngilizce’yi kullanarak kullanıcıya bildirim yapılması sağlanabilir.
// values
static values = {
notifyMessage: {
type: String,
default: 'Copied!' // value if not defined as data attr
}
}
Yukarıda dikkat edilmesi gereken bir diğer husus, HTML’de kebab-case olarak tanımlanan notify-message
değişkeninin Stimulus’ta camelCase’e dönüşmesidir. Naming convention’a dikkat edilmesi gerekmektedir.4
Methodlar:
Öncelikle copy
methodumuzla başlayalım ve bu method’un clipboard ikonuna tıklandığında çalışacağını hatırlayalım. Targetlara this.[targetName]Target
şeklinde erişilmektedir ve bu methodda textContainerTarget
‘ın innerText
‘i clipboard’a yazılmıştır (kopyalanmıştır).
copy(event) {
event.preventDefault()
event.stopPropagation()
const text = this.textContainerTarget.innerText
navigator.clipboard.writeText(text)
}
Elimizdekileri birleştirirsek:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static values = {
succesMessage: {
type: String,
default: 'Copied!'
}
}
static targets = ['textContainer', 'clipboardButton']
copy(event) {
event.preventDefault()
event.stopPropagation()
const text = this.textContainerTarget.innerText
navigator.clipboard.writeText(text)
}
}
Şu an aslında controllerda pnaoya kopyalama işlemi yapılabilmektedir. Fakat durumun başarılı olduğunu kullanıcıya ifade etmek için bazı eklemeler yapmamız gerekiyor.. succesMessage
‘ı henüz kullanmadık.
Yapacağımız işlem aslında basitçe notifyUI
methodu aracılığıyla kopyalama ikonunun içeriğini değiştirip, bir süre sonra eski haline döndürülmesidir.
Panoya kopyalama işlemi async bir işlem oldugu için navigator.clipboard.writeText(text).then(notifyUI)
şeklinde ekrana feedback veren bir method tanımlamamız gerekmektedir.
Bunu sağlamak için setTimeout
methodunu kullanmak gereklidir.
Bunun için öncelikle state’i (yani eski haline dönüşünü) sağlayabilmek için Stimulus’un callback actionlarindan olan connect()
methodunu kullanalım ve innerHTML’ın eski halini hafızaya alalım.
connect
methodu controller DOM’a her bağlandığında çalışmaktadır. 5
connect() {
this.clipboardButtonInitialInnerHTML = this.clipboardButtonTarget.innerHTML
}
notifyUI
methodunu ekleyelim.
notifyUI() {
this.clipboardButtonTarget.innerHTML = this.notifyMessageValue
setTimeout(() => {
this.clipboardButtonTarget.innerHTML = this.clipboardButtonInitialInnerHTML
}, 2000)
}
Özetle: Yukarıdaki kod parçası, kopyalama işlemi başarılı olduğunda kullanıcıya bildirim vermek ve ikonu eski haline döndürmek için kullanılmaktadır. notifyUI
methodu, navigator.clipboard.writeText(text)
işleminin ardından çalışır.
İlk olarak, ikonun içeriğini successMessageValue
ile değiştirmektedir, böylece kullanıcıya başarılı bir kopyalama işlemi olduğunu bildirir. Ardından, setTimeout
kullanarak 2 saniye sonra ikonun orijinal halini geri almasını sağlamaktadır.
Elimizdeki tüm bu methodları birleştirdiğimizde clipboard_controller.js
dosyasının son hali aşağıdaki gibi olacaktır.
Bu yazıda ‘copy to clipboard’ fonksiyonalitesi sağlamak için ilgili controller’ın oluşturulması üzerinden temel Stimulus yöntemleri üzerine konuştuk.
Faydalı kaynaklar: