Tech: getElementById Hanya Akan Ambil Yang Pertama

Ada satu masalah petang semalam kepada seorang intern yang mana dia mahu membuat fungsi add to chart menggunakan javascript dan jquery kepada item yang diletakkan di dalam owl carousel tetapi yang peliknya daripada 20 item, hanya 10 item pertama sahaja yang boleh dimasukkan, selebihnya tidak dapat. dia memanggil satu function javascript apabila butang add to cart tersebut di tekan. Kita anggapkan sebagai addToChart(counter, item.id). Aku cuba untuk menjalankan secara manual dengan meletakkan kod tersebut di dalam snippet dan menjalankannya, function tersebut berjalan dengan jayanya. Maka kemungkinan function tersebut bermasalah boleh ditolak.

Aku cuba sekali lagi untuk menjalankan secara manual tetapi kali ini untuk mengubah textContent elemen tersebut dengan membuat $('#item-11').html('testing') dan fungsi tersebut juga tiada masalah. Cuma yang anehnya tiada sebarang perubahan yang terjadi kepada paparan. Tetapi jika di cari kembali di dalam element tab, perubahan tersebut berlaku. Cuma bukan pada tempatnya.

Setelah dicari lebih lanjut, aku perasan own carousel akan membuat clone separuh daripada senarai di atas senarai yang asal. Contohnya begini;

Senarai asal

  • item-1
  • item-2
  • item-3
  • item-4

Senarai tambahan

  • item-3 (clone)
  • item-4 (clone)
  • item-1
  • item-2
  • item-3
  • item-4
  • item-1 (clone)
  • item-2 (clone)

Aku nampak kerana mahu menjadikan slide tersebut tidak berpecah atau terpisah semasa mahu membuat pusingan. Dan disebabkan itu juga id yang mahu dibuat tidak dapat dimasukkan. Maka aku mencadangkan tukar kepada class dan masalah tersebut selesai.

Aku masih musykil kerana jika id tersebut diletakkan sebagai item-3 clone sepatutnya adalah unik berbanding item-3 sahaja. Dan aku telah cuba dengan membuat contoh mudah.

<div class="ul">
    <li id="basket-3">3 clone</li>
    <li id="basket-4">4 clone</li>
    <li id="basket-1">1</li>
    <li id="basket-2">2</li>
    <li id="basket-3">3</li>
    <li id="basket-4">4</li>
    <li id="basket-1">1 clone</li>
    <li id="basket-2">2 clone</li>
</div>

<script>
   $(function(){
        console.log($('#basket-3').text());
        console.log($('#basket-4').text());
        console.log($('#basket-3').attr('id', 'basket-3 clone'));
        console.log($('#basket-4').attr('id', 'basket-4 clone'));
        console.log($('#basket-3').text());
        console.log($('#basket-4').text());
   })
</script>

Dan daripada log, aku nampak sepert ini yang mana aku nampak mengikut konsep javascript yang biasa. Hari ini aku akan tengok balik apa masalah sebenarnya daripada own carousel tu.

javascript get element by id

Tech: Brew PHP Upgrade

Aku tak pasti kenapa dan mengapa diorang tukar kaedah simpan keg untuk php daripada php71 kepada [email protected]. Mungkin disebabkan pertukaran daripada homebrew/php kepada homebrew/core cuma aku perasan beberapa perkara;

Tidak konsistan

[email protected] untuk php 7.1 tetapi php untuk php 7.2. Apa akan jadi jika php 7.3 atau 8.0 keluar?

non suffix php version brew
https://github.com/Homebrew/homebrew-core/pull/26137#pullrequestreview-109196492

Library asas telah dimasukkan sekali

jika dulu perlu brew install php71-intl kini tidak perlu kerana intl telah dimasukkan secara automatik. Dan ini juga menyebabkan ralat tidak perlu jika anda mempunyai external config sebelum ini.

Sukar untuk membuat pertukaran versi php

Disebabkan kaedah baru ini, agak sukar untuk membuat pertukaran antara versi dan kita perlu berjaga-jaga dengan tetapan sistem apabila keluarnya versi terkini PHP contohnya;

  • sekarang versi terkini php 7.2 – nama direktori php 7.2 => php
  • akan datang versi terkini php 7.3 – nama direktori php 7.2 => [email protected]

Maka semua projek yang menggunakan versi 7.2 yang tidak berhajat untuk masuk ke versi 7.3 perlu menukar tetapan php.

Secara positifnya, kita akan memastikan sistem kita sentiasa boleh dijalankan pada php yang terkini. Cuma, tidak semua klien boleh membuat kemaskini php versi terkini terutamanya badan kerajaan ehem.

Dan dengan ini juga, semasa menjalankan arahan composer, anda harus berhati-hati dengan versi php di cli. Aku gunakan tetapan interpreter dalam phpstorm. Jika tidak aku cadangkan membuat alias kepada setiap versi yang mahu digunakan.

Ralat

path

If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/[email protected]/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/[email protected]/sbin:$PATH"' >> ~/.bash_profile

Sila pastikan di dalam .bash_profile anda telah diletakkan pada versi yang mahu digunakan.

library, extension

/usr/local/etc/httpd/httpd.conf: Cannot load /usr/local/Cellar/php71/7.1.12_23/libexec/apache2/libphp7.so into server: dlopen(/usr/local/Cellar/php71/7.1.12_23/libexec/apache2/libphp7.so, 10): image not found

Disebabkan beberapa extension telah dimasukkan secara automatik dan dijalankan terus, anda perlu memastikan external configuration (dalam kes ini httpd.conf) atau autoloader tidak memanggil semula extension tersebut.

Periksa juga di dalam <span class="s1">/usr/local/etc/php untuk memastikan tiada konfigurasi lain yang mengganggu.

brew php remove autoloader
https://github.com/Homebrew/homebrew-php/issues/4826#issuecomment-377548781

Anda hanya perlu membuat komen atau memadamkan baris yang memanggil extension tersebut.

Notakaki: jika anda tidak mempunyai sebarang keperluan untuk upgrade, jangan upgrade. Guna apa yang ada.

Tech: CSS Grid – fr

Sebelum ini aku telah ceritakan bagaimana grid dalam css berfungsi, maka untuk kali ini aku sambung sedikit lagi sekitar perkara ini.

Di dalam CSS Grid, terdapat satu unit yang diperkenalkan, fr iaitu fraction.

Kegunaan fr dapat ditonjolkan dengan situasi seperti ini;

<!doctype html>
<html lang="en">
<head>
    <style>
        body {
            margin-top: 40px;
        }

        #container {
            width: 800px;
            margin: auto;
            background: #e3e3e3;

            display: grid;
            grid-template-columns: 100px 100px 100px;
            grid-template-rows: repeat(3, 50px);
            grid-gap: 1em;
        }

        #container > div {
            background: #999;
            font-weight: bold;
            color: white;
            font-family: sans-serif;
        }
    </style>
</head>
<body>
<section id="container">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</section>
</body>
</html>

Aku ada 3 kotak, dua kotak pertama bersaiz 100px dan kotak ketiga aku mahukan dia mengambil baki saiz yang ada. Dalam kes ini 800px - 100px - 100px - 1em - 1em. Ya aku boleh capai dengan kaedah begitu tetapi sedikit “matematik”.

Maka diperkenalkan unit fr atau fraction ke dalam CSS grid. Tugasnya adalah untuk mengambil bahagian baki yang ada berdasarkan pecahan yang dinyatakan.

Sebagai contoh apabila kita tukarkan grid-template-columns: 100px 100px 100px; kepada grid-template-columns: 100px 100px 1fr;,  secara automatik browser akan membuat kiraan untuk kita seperti ini;

jumlah width = 800px
jumlah width telah digunakan = 100px + 100px
jumlah grid-gap dan margin = 1em + 1em
jumlah pecahan = 1
pecahan semasa = 1

baki width = 800px - 100px - 100px - 1em - 1em
           = 568px

∴ width grid pecahan = baki width * (pecahan semasa / jumlah pecahan)
                     = 568px * 1/1
                     = 568px

Yang akan menghasilkan grid kiraan manual tadi.

css-grid-fr-unit

Soalan: Jika boleh menggunakan kaedah manual, mengapa perlu menggunakan kaedah fr?

Jawapan: Jika kita memerlukan fr lebih daripada satu, maka kiraan manual akan menjadi rumit. Sebagai contoh;

kotak 1 = 100px

kotak 2 = 2/3 daripada baki width

kotak 3 = 1/3 daripada baki width

Dengan menggunakan kaedah fr, kita hanya perlu menukarkan kepada grid-template-columns: 100px 2fr 1fr; yang akan memberikan arahan kepada browser untuk memberikan 2 bahagian daripada 3 (2fr + 1fr) kepada kotak 2 dan 1 bahagian kepada kotak 3.

css grid 2 fr

Kaedah ini juga lebih kurang sama dengan flex: flex: 100px 2 1; tetapi seperti mana yang aku katakan pada entri yang sebelum ini, terdapat perbezaan keperluan untuk flex dan grid.

Nota: entri ini aku kecilkan kepada fraction sahaja kerana entri lepas terlalu banyak gambar.

Tech: Nativescript iOS – Unable to apply changes on device

Aku dalam proses membuat satu percubaan untuk membina satu aplikasi mobil untuk sistem HR menggunakan Nativescript + Vuejs. Tetapi apabila aku cuba jalankan kod ke dalam emulator terdapat ralat yang menganggu.

Ceritanya, apabila aku jalankan arahan yarn run watch:ios pada terminal akan keluar ralat seperti dibawah;

Unable to apply changes on device: <device_id>. Error is: Command failed: ruby -e "require 'xcodeproj'; Xcodeproj::Config.new('/Users/syafiq/Developer/ost-hr-mobile/dist/platforms/ios/plugins-debug.xcconfig').merge(Xcodeproj::Config.new('/Users/syafiq/Developer/ost-hr-mobile/dist/app/App_Resources/iOS/build.xcconfig')).save_as(Pathname.new('/Users/syafiq/Developer/ost-hr-mobile/dist/platforms/ios/plugins-debug.xcconfig'))"
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- xcodeproj (LoadError)
        from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from -e:1:in `<main>'

Daripada pembacaan aku, orang di internet mencadangkan untuk membuat diagnos menggunakan tns doctor (macam brew doctor untuk tujuan diagnos),

WARNING: xcodeproj gem is not installed or is not configured properly.
You will not be able to build your projects for iOS.
To be able to build for iOS and run apps in the native emulator, verify that you have installed xcodeproj.

Maka aku pasang pakej xcodeproj dengan command gem install xcodeproj. Setelah selesai aku jalankan semula arahan yarn run watch:ios dan akhirnya aku dapat jalankan kod ini di dalam emulator.

Nota: Nativescript + Vuejs baru dalam versi 1.0, maka sebenarnya tidak berapa sesuai untuk digunakan untuk sistem yang sebenar. Aku jadikan sistem HR dalaman sebagai bahan eksperimen untuk mengetahui sejauh mana fungsi yang ada di dalam versi Vuejs ini. Fungsi yang aku cuba akan masukkan adalah authentication dan geolocation dahulu. Kamera, autosync dan lain-lain akan menyusul.

Tech: Redirect Berdasarkan Role Selepas Log Masuk

Aku adaptasi artikel ini daripada artikel asal, Redirect after login or register in Laravel: Adding a custom method. Aku ada dua jenis pengguna:

  1. Pengguna berdaftar
  2. Admin sistem

Dan aku perlukan mereka ini dihantar kepada dua tempat berlainan selepas proses log masuk.

Pengguna URL
Pengguna Berdaftar /home
Admin Sistem /admin

Aku gunakan modul auth daripada Laravel, daripada LoginController ada satu variable yang menyatakan url yang diletakkan secara lalai untuk sebarang log masuk yang berjaya dibuat.

/**
 * Where to redirect users after login.
 *
 * @var string
 */
protected $redirectTo = '/home';

Kita boleh mengubah variable tersebut kepada function untuk memudahkan membuat if else. Kenapa tidak menggunakan ternary atau if else biasa sahaja seperti kod di bawah?

/**
 * Where to redirect users after login.
 *
 * @var string
 */
if(auth()->user()->is_admin) {
  protected $redirectTo = '/admin';
} else {
  protected $redirectTo = '/home';
}

// atau

protected $redirectTo = auth()->user()->is_admin ? '/admin' : '/home';

Untuk memudahkan proses membuat test script dan masih boleh digunakan jika sistem perlu menambah golongan ketiga, keempat mahu pun kelima kelak. Lebih future proof.

Maka daripada kod asal, aku tukarkan kepada kod ini;

/**
 * Where to redirect users after login.
 *
 * @return string
 */
public function redirectTo(): string
{
    if(auth()->user()->is_admin) {
        return '/admin';
    } else {
        return '/home';
    }
}

Dengan ini, apabila pengguna dapat membuat log masuk ke dalam sistem, sistem akan terus menyemak adakah pengguna ini seorang admin atau pengguna biasa, jika admin sistem akan membawanya kepada paparan admin. Jika tidak maka pengguna tersebut akan dibawa kepada paparan pengguna biasa.

Nota: Kaedah ini tidak akan menyelesaikan masalah jika pengguna biasa masuk ke paparan admin menggunakan kaedah menukar alamat laman web. Untuk menyelesaikan masalah ini sila gunakan middleware atau fungsi di dalam route untuk memastikan hanya admin yang boleh masuk ke paparan admin.