7 minutes
Supersimple To-do
Jadi ceritanya saya pengen menata hidup, biar gak amburadul mulu. Kayaknya saya butuh nulisin rencana harian. Sialnya, kalau nulis di buku catatan saya suka lupa (dan males) dibawa bukunya. Belum lagi pulpen yang sering ilang.
Ya udah, saya bikin aja pake javascript. Biar bisa diakses di browser smartphone. Lagian, kalau smartphone kan pasti dibawa-bawa. Kenapa gak download aplikasinya aja malah cape-cape bikin? Karena gak rame!
Hidup harus ada tantangannya bos! haha.
Nanti hasilnya bakal begini:
Aplikasi ini juga cemen. Banyak kekurangannya, man. Saya mengamini apa yang Pandji bilang bahwa bikin aja dulu, kemudian bertumbuh.
Note: Saya hanya menjelaskan syntax, method, dan property yang belum pernah saya tulis.
The Gut
Seperti To-do List pada umumnya, yang dilakukan ketika merencanakan apa yang akan dilakukan adalah:
- Buka buku catatan.
- Tulis daftar kegiatan-kegiatannya.
- Coret kegiatan yang sudah dilakukan.
Karena ini pake teknowlowgeee.. berarti yang harus saya lakukan menjadi:
- Buka browser, kunjungi link Supersimple To-do
- Tulis daftar kegiatan-kegiatannya.
- Coret kegiatan yang sudah dilakukan.
Look, cuman daftar nomor 1 doang yang beda, sisanya sama.
The Building
Pertama, saya bikin dulu HTML-nya. Easy peasy, man.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="css/style.css">
<title>do-List</title>
</head>
<body>
<h1 class="title">Gawean!</h1>
<p id="time"></p>
<div>
<input type="text" id="inputList">
<button id="addBtn">add</button>
</div>
<ul id="toDoList"></ul>
<button id="rstBtn">reset</button>
<footer>
<p>
["<a href="">baca dokumentasi</a>" , "dari <a href="https://dekadesniotak.id">dekadensiotak</a> untuk kamu</a>", "❤"]
</p>
</footer>
<script async src="js/script.js"></script>
</body>
</html>
Perhatikan, saya tambahin id
di setiap tag yang saya ingin modifikasi pake javascript nantinya.
Mari saya bahas yang menurut saya penting di HTML tersebut.
<!DOCTYPE html>
Adalah sebuah deklarasi untuk memastikan bahwa dokumen akan di-parse dengan cara yang sama di berbagai browser.
lang
Adalah sebuah atribut pada tag <html>
yang berfungsi untuk memberi tahu bahasa apa yang akan dipakai di konten dokumennya. Ini berguna untuk membantu search engine dan browser, salah satunya adalah penerjemahan.
Saya menggunakan atribut lang="id"
karena kontennya pake bahasa indonesia. Padahal isi <button>
pake bahasa inggeris. haha
Bisa lihat ISO 639-1 untuk daftar language code, siapa tau kamu mau pake bahasa Swahili tapi gak tau kodenya, misalnya.
<meta>
Merupakan sebuah tag yang ngasih tau data dari sebuah dokumen. Nantinya data-data ini bisa ditampilkan di hasil pencarian search engine atau twitter card atau feed-feed yang lain lah, yang membolehkan data ini tampil.
-
charset : ngasih tau kalau halaman ini karakter encoding-nya apa.
- utf-8 : karakter encoding paling umum yang direkomendasikan.
-
name : ngasih tau nama dari
content
.- viewport : ngatur layout untuk mobile browser.
-
content : isi dari
name
yang udah di deklarasikan sebelumnya.- width=device-width : lebar dari device yang diset 100%.
- initial-scale=1.0 : zoom level saat halaman pertama kali ditampilkan.
-
http-equiv : mendefinisikan arahan http.
- X-UA-Compatible : untuk milih versi dari Internet Explorer yang bisa ngerender halamannya.
- ie=edge : versi dari Internet Explorer
emang masih ada yang pake internet explorer? Ya siapa tau.
async
Atribut pada tag <script>
supaya file javascriptnya di parse bareng-bareng sama file html.
The Style
Lalu, saya tambahin CSS biar kece. Karena kata saya mah gak ada yang terlalu penting buat dibahas, jadi liat aja CSS-nya di sini aja. Kalau gak mau pake CSS juga gapapa, cuman gak asoy aja diliatnya. Walaupun CSS saya juga gak terlalu asoy. haha
The Code
Finally, the main character, javascript!
1. Get the elements
Pertama-tama, saya tangkap dulu semua tag html yang bakal saya modifikasi dengan getElementById()
yang merupakan sebuah method untuk ngambil tag html dengan id
tertentu. Kebetulan semuanya saya pakein id
bukan class
. Karena saya yakin elemen-elemen itu cuman satu doang. Pake const
juga karena yakin nilainya gak akan diubah.
const time = document.getElementById('time');
const inputList = document.getElementById('inputList');
const addBtn = document.getElementById('addBtn');
const toDoList = document.getElementById('toDoList');
const rstBtn = document.getElementById('rstBtn');
2. Set the date
Lalu, kita set dulu time
jadi tanggal yang sesuai dengan tanggal saat si halaman dibuka.
const options = {weekday : "long", day:"numeric", month:"long", year:"numeric"};
const today = new Date();
time.textContent = today.toLocaleDateString("id-ID", options);
Date()
Adalah sebuah objek yang merepresentasikan waktu yang terekam di komputer. Isinya number
dalam milidetik sejak 1 Januari 1970.
Saya inisialisasi objek Date()
dengan nama today
. Tentu saja harus pake operator new
.
toLocaleDateString()
Adalah sebuah method yang mengembalikan nilai string dari suatu tanggal objek Date()
.
Syntax:
objDate.toLocaleDateString([locales], [options])
Objek Date()
saya adalah today
, jadi saya modifikasi itu menjadi string dengan format tanggal Indonesia. Caranya dengan memasukan "id-ID"
sebagai parameter locales
untuk format penanggalan Indonesia.
Untuk parameter options
, sebuah objek dibutuhkan untuk modifikasi lebih lanjut format si tanggalnya. Objek itu saya buat dengan nama options
. Pilihan value dari locales
dan options
ada banyak.
Untuk ditampilin ke halaman, saya pake properti textContent
.
3. Focus on input
inputList.focus();
Biar user bisa langsung ngetik, saya fokusin ke inputnya dengan method focus()
.
4. Enter key as click
inputList.addEventListener('keyup', function(event) {
if (event.code === 'Enter') {
addBtn.click();
}
});
Saya suka males kalau harus ngarahin pointer dulu ke button. Mending langsung mencet enter aja. Kalau di henpun sih gak ngaruh kayaknya ya?
5. Click to function
addBtn.addEventListener('click', addList);
rstBtn.addEventListener('click', rstList);
addBtn
nge-trigger fungsi addList()
. Sedangkan rssBtn
nge-trigger fungsi rstList()
.
6. Add the list
function addList() {
const list = document.createElement('li');
const inputValue = inputList.value;
if (inputValue === '') {
alert('input tidak boleh kosong!');
} else {
list.textContent = inputValue;
toDoList.appendChild(list);
}
inputList.value = '';
}
Ok, untuk list item yang bakal tampil, saya bikin dulu element li
untuk nantinya ditempatik di dalem tag ul
dengan representasi toDoList
. Isi dari inputnya, yang bakal jadi list item, saya ambil pake properti .value
dari inputList
.
Lalu saya gunakan pengkondisian. Jika user gak ngisi apa-apa, saya kasih alert()
yang munculin alert box dengan text input tidak boleh kosong
. Kalau user ngisi sesuatu, maka bakal ditampilin sebagai konten dari list
yang elemennya tadi udah dibuat.
Terakhir, saya kosongin lagi inputList
-nya biar user gak usah ribet mencet backspace.
7. Strikethrough list item when clicked
const listed = document.querySelector('ul');
listed.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
event.target.classList.toggle('strikeList');
}
});
Ketika si user ngeklik list item, si list item itu bakal dicoret. Ibaratnya ini ketika user udah beres ngelakuin salah satu to-do-nya.
Saya ambil dulu query ul
nya yang nampung li
dengan konten list item yang telah diinput sama user. Terus kasih event kalau si user ngklik tag yang namanya LI
maka tulisannya bakal dicoret pake CSS yang ngarah ke class strikeList
.
tagName
Adalah properti dari objek Element
mengembalikan nilai sebuah nama tag yang dipanggil. Nah, si nama tag selalu dikembalikan dengan huruf besar alias uppercase. Mangkanya saya nulisnya LI
bukan li
.
classList
Merupakan sebuah properti yang mengembalikan nama class sebuah elemen sebagai objek DOMTokenList.
toggle()
Nah, ini adalah salah satu method dari objek DOMTokenList
. Method ini menambahkan token jika tidak ada sebelumnya serta memberi nilai true
, dan melepas token jika sudah ada serta memberi nilai false
. Apa token-nya? Harus merupakan DOMString. String aja lah biar gampang, soalnya javascript udah pake itu. Dalam kasus ini, saya ngasih string strikeList
yang merupakan nama class, karena saya pake method ini untuk melakukan aksi kepada objek classList
yang nilainya merupakan objek DOMTokenList
.
8. Reset the list
function rstList() {
const sure = confirm('are you sure?');
if (sure === true) {
const resetList = document.querySelectorAll('#toDoList li');
for (let i = 0 ; i < resetList.length ; i++) {
resetList[i].textContent = '';
}
}
}
Bagaimana jika semua list item sudah dicoret dan ingin memulai list baru? Reset tentu dibutuhkan.
Pertama-tama, saya perlu konfirmasi kalau-kalau button-nya kepencet.
confirm()
Adalah sebuah method yang munculin dialog box dengan pesan tertentu (pesan yang saya kasih: are you sure?
). Method ini akan mengembalikan nilai true
jika dipencet OK dan akan mengembalikan nilai false
jika dipencet Cancel.
Lalu, saya kasih pengkondisian. Jika user mencet OK, berarti itu adalah true
, maka elemen-elemen li
yang udah jadi array karena querySelectorAll()
bakal dikasih nilai string kosong ''
pada setiap kontennya.
The Result
Hasilnya sesuai dengan keiingan saya, kalau di PC. Kalau di smartphone gak mau dicoret euy itu resultnya. Terus kalau di refresh ilang. Hahaha. Yaeyalah, orang gak ada penyimpanan datanya. Hehe.
Kayaknya saya harus ngegali touch events dan JSON deh. Di postingan berikutnya ya.
Yang mau coba, silakan: https://dekadensiotak.github.io/supersimple-todo/
Nih kalau yang mau ngintip source code-nya: [https://github.com/dekadensiotak/supersimple-todo][https://github.com/dekadensiotak/supersimple-todo]
Kalau kamu suka tulisan saya, boleh kok traktir saya kopi. Tinggal klik di sini.