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: supersimple to-do

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:

  1. Buka buku catatan.
  2. Tulis daftar kegiatan-kegiatannya.
  3. Coret kegiatan yang sudah dilakukan.

Karena ini pake teknowlowgeee.. berarti yang harus saya lakukan menjadi:

  1. Buka browser, kunjungi link Supersimple To-do
  2. Tulis daftar kegiatan-kegiatannya.
  3. 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]