Unit 6: Menggunakan Library atau Komponen Pre-Existing

Mempelajari cara mengintegrasikan library CSS/JS populer, membaca dokumentasi, dan mengimplementasikan komponen siap pakai untuk mempercepat pengembangan web.

Estimasi: 10 Jam 3 Sub Materi

Tujuan Pembelajaran

  • Mengintegrasikan library CSS populer
  • Menggunakan JavaScript library/framework
  • Membaca dan menerapkan dokumentasi
  • Implementasi plugin pihak ketiga

1. CSS Frameworks (Bootstrap & Tailwind)

Bootstrap Framework

Bootstrap adalah framework CSS yang paling populer untuk membangun responsive web design dengan cepat.

Bootstrap 5

Grid system, components, utilities

Dokumentasi
Tailwind CSS

Utility-first CSS framework

Dokumentasi
Bootstrap Grid System
<!-- Bootstrap CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- Container dan Grid -->
<div class="container">
    <div class="row">
        <div class="col-md-6 col-lg-4">
            <div class="card">
                <div class="card-body">
                    <h5 class="card-title">Card Title</h5>
                    <p class="card-text">Some content here</p>
                    <a href="#" class="btn btn-primary">Button</a>
                </div>
            </div>
        </div>
        <div class="col-md-6 col-lg-8">
            <form>
                <div class="mb-3">
                    <label for="email" class="form-label">Email</label>
                    <input type="email" class="form-control" id="email">
                </div>
                <div class="mb-3">
                    <label for="password" class="form-label">Password</label>
                    <input type="password" class="form-control" id="password">
                </div>
                <button type="submit" class="btn btn-success">Submit</button>
            </form>
        </div>
    </div>
</div>

<!-- Navigation Bar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container">
        <a class="navbar-brand" href="#">My Website</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav ms-auto">
                <li class="nav-item">
                    <a class="nav-link active" href="#">Home</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">About</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Contact</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
Bootstrap Components
Demo: Bootstrap Components
Alerts:
Buttons:
Badges:
Primary Success Warning Danger
Progress Bar:
75%
Tailwind CSS Utility Classes
<!-- Tailwind CDN -->
<script src="https://cdn.tailwindcss.com"></script>

<!-- Utility Classes Examples -->
<div class="max-w-4xl mx-auto p-6">
    <!-- Card dengan Tailwind -->
    <div class="bg-white rounded-lg shadow-lg overflow-hidden">
        <img class="w-full h-48 object-cover" src="image.jpg" alt="Card image">
        <div class="p-6">
            <h2 class="text-2xl font-bold text-gray-800 mb-2">Card Title</h2>
            <p class="text-gray-600 mb-4">Card description with some text content.</p>
            <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
                Read More
            </button>
        </div>
    </div>

    <!-- Grid Layout -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mt-8">
        <div class="bg-gray-100 p-4 rounded">Item 1</div>
        <div class="bg-gray-100 p-4 rounded">Item 2</div>
        <div class="bg-gray-100 p-4 rounded">Item 3</div>
    </div>

    <!-- Responsive Typography -->
    <h1 class="text-3xl md:text-4xl lg:text-5xl font-bold text-center mt-8">
        Responsive Heading
    </h1>
    
    <!-- Flexbox Layout -->
    <div class="flex flex-col md:flex-row items-center justify-between mt-8">
        <div class="mb-4 md:mb-0">
            <h3 class="text-xl font-semibold">Flexbox Content</h3>
        </div>
        <div class="space-x-2">
            <button class="bg-green-500 text-white px-4 py-2 rounded">Save</button>
            <button class="bg-red-500 text-white px-4 py-2 rounded">Cancel</button>
        </div>
    </div>
</div>

2. JavaScript Libraries

jQuery Library

jQuery adalah library JavaScript yang menyederhanakan manipulasi DOM, event handling, dan AJAX.

jQuery

Write less, do more

Modern Libraries

React, Vue, Angular

Specialized

Chart.js, D3.js, etc.

jQuery Basics
<!-- jQuery CDN -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<script>
// Document ready
$(document).ready(function() {
    console.log('jQuery loaded and DOM ready');
    
    // Element selection
    const title = $('#main-title');
    const buttons = $('.btn');
    const allParagraphs = $('p');
    
    // Event handling
    $('#myButton').click(function() {
        $(this).text('Clicked!');
        $(this).addClass('btn-success');
    });
    
    // Form submission
    $('#contactForm').submit(function(e) {
        e.preventDefault();
        
        const name = $('#name').val();
        const email = $('#email').val();
        
        if (name === '' || email === '') {
            alert('Please fill all fields');
            return;
        }
        
        // AJAX request
        $.ajax({
            url: 'submit-form.php',
            method: 'POST',
            data: {
                name: name,
                email: email
            },
            success: function(response) {
                $('#result').html('<div class="alert alert-success">Form submitted successfully!</div>');
                $('#contactForm')[0].reset();
            },
            error: function() {
                $('#result').html('<div class="alert alert-danger">Error submitting form</div>');
            }
        });
    });
    
    // Animation effects
    $('.fade-btn').click(function() {
        $('.fade-target').fadeToggle();
    });
    
    $('.slide-btn').click(function() {
        $('.slide-target').slideToggle();
    });
    
    // Dynamic content manipulation
    $('#addItem').click(function() {
        const newItem = '<li class="list-group-item">New Item ' + Date.now() + '</li>';
        $('#itemList').append(newItem);
    });
    
    // Event delegation for dynamic content
    $(document).on('click', '.remove-item', function() {
        $(this).parent().fadeOut(function() {
            $(this).remove();
        });
    });
});
</script>
Modern JavaScript Alternatives
// Vanilla JavaScript equivalents to jQuery

// Document ready
document.addEventListener('DOMContentLoaded', function() {
    console.log('DOM loaded and ready');
});

// Element selection
const title = document.getElementById('main-title');
const buttons = document.querySelectorAll('.btn');
const firstParagraph = document.querySelector('p');

// Event handling
document.getElementById('myButton').addEventListener('click', function() {
    this.textContent = 'Clicked!';
    this.classList.add('btn-success');
});

// Fetch API for AJAX
async function submitForm(formData) {
    try {
        const response = await fetch('submit-form.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(formData)
        });
        
        const result = await response.json();
        
        if (response.ok) {
            showMessage('success', 'Form submitted successfully!');
        } else {
            showMessage('error', 'Error submitting form');
        }
    } catch (error) {
        console.error('Error:', error);
        showMessage('error', 'Network error');
    }
}

// Utility functions
function showMessage(type, message) {
    const resultDiv = document.getElementById('result');
    resultDiv.innerHTML = `<div class="alert alert-${type}">${message}</div>`;
}

function fadeToggle(element) {
    if (element.style.opacity === '0') {
        element.style.opacity = '1';
    } else {
        element.style.opacity = '0';
    }
}

// Modern class-based approach
class FormHandler {
    constructor(formSelector) {
        this.form = document.querySelector(formSelector);
        this.init();
    }
    
    init() {
        this.form.addEventListener('submit', this.handleSubmit.bind(this));
    }
    
    async handleSubmit(e) {
        e.preventDefault();
        const formData = new FormData(this.form);
        await this.submitData(formData);
    }
    
    async submitData(formData) {
        // Submit logic here
    }
}

// Usage
const contactForm = new FormHandler('#contactForm');
Chart.js untuk Visualisasi Data
Demo: Chart.js Implementation
Chart Controls:

3. Plugin Integration & Third-party Components

Popular Plugins

Mengintegrasikan plugin populer untuk meningkatkan fungsionalitas website.

Date Picker Implementation
<!-- Flatpickr Date Picker -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>

<!-- HTML -->
<input type="text" id="datepicker" class="form-control" placeholder="Select a date">
<input type="text" id="datetimepicker" class="form-control" placeholder="Select date and time">
<input type="text" id="rangepicker" class="form-control" placeholder="Select date range">

<script>
// Basic date picker
flatpickr("#datepicker", {
    dateFormat: "Y-m-d",
    minDate: "today"
});

// Date and time picker
flatpickr("#datetimepicker", {
    enableTime: true,
    dateFormat: "Y-m-d H:i",
    time_24hr: true
});

// Date range picker
flatpickr("#rangepicker", {
    mode: "range",
    dateFormat: "Y-m-d",
    onChange: function(selectedDates, dateStr, instance) {
        console.log('Selected range:', dateStr);
    }
});
</script>
Image Carousel/Slider
<!-- Swiper.js Carousel -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css">
<script src="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js"></script>

<!-- HTML Structure -->
<div class="swiper mySwiper">
    <div class="swiper-wrapper">
        <div class="swiper-slide">
            <img src="https://picsum.photos/800/400?random=1" alt="Image 1" class="w-100">
            <div class="carousel-caption">
                <h5>Slide 1</h5>
                <p>Beautiful landscape image</p>
            </div>
        </div>
        <div class="swiper-slide">
            <img src="https://picsum.photos/800/400?random=2" alt="Image 2" class="w-100">
            <div class="carousel-caption">
                <h5>Slide 2</h5>
                <p>Amazing architecture</p>
            </div>
        </div>
        <div class="swiper-slide">
            <img src="https://picsum.photos/800/400?random=3" alt="Image 3" class="w-100">
            <div class="carousel-caption">
                <h5>Slide 3</h5>
                <p>Nature photography</p>
            </div>
        </div>
        <div class="swiper-slide">
            <img src="https://picsum.photos/800/400?random=4" alt="Image 4" class="w-100">
            <div class="carousel-caption">
                <h5>Slide 4</h5>
                <p>Urban landscape</p>
            </div>
        </div>
    </div>
    
    <!-- Navigation buttons -->
    <div class="swiper-button-next"></div>
    <div class="swiper-button-prev"></div>
</div>

<!-- CSS -->
<style>
.mySwiper {
    width: 100%;
    height: 400px;
    margin: 20px 0;
    border-radius: 10px;
    overflow: hidden;
}

.swiper-slide {
    position: relative;
    text-align: center;
    font-size: 18px;
    background: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
}

.swiper-slide img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.carousel-caption {
    position: absolute;
    bottom: 20px;
    left: 20px;
    right: 20px;
    background: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 15px;
    border-radius: 5px;
}

.carousel-caption h5 {
    margin-bottom: 5px;
    font-size: 1.2rem;
}

.carousel-caption p {
    margin: 0;
    font-size: 0.9rem;
}

/* Custom pagination styling */
.swiper-pagination-bullet {
    width: 12px;
    height: 12px;
    background: rgba(255, 255, 255, 0.5);
    opacity: 1;
}

.swiper-pagination-bullet-active {
    background: #007bff;
}

/* Custom navigation buttons */
.swiper-button-next,
.swiper-button-prev {
    color: #007bff;
    background: rgba(255, 255, 255, 0.8);
    width: 40px;
    height: 40px;
    border-radius: 50%;
}

.swiper-button-next:after,
.swiper-button-prev:after {
    font-size: 16px;
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .mySwiper {
        height: 250px;
    }
    
    .carousel-caption h5 {
        font-size: 1rem;
    }
    
    .carousel-caption p {
        font-size: 0.8rem;
    }
}
</style>

<!-- JavaScript -->
<script>
// Initialize Swiper
const swiper = new Swiper('.mySwiper', {
    // Basic settings
    slidesPerView: 1,
    spaceBetween: 0,
    loop: true,
    
    // Autoplay
    autoplay: {
        delay: 4000,
        disableOnInteraction: false,
        pauseOnMouseEnter: true,
    },
    
    // Pagination
    pagination: {
        el: '.swiper-pagination',
        clickable: true,
        dynamicBullets: true,
        renderBullet: function (index, className) {
            return '<span class="' + className + '">' + (index + 1) + '</span>';
        },
    },
    
    // Navigation arrows
    navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
    },
    
    // Keyboard control
    keyboard: {
        enabled: true,
    },
    
    // Mouse wheel control
    mousewheel: {
        invert: false,
    },
    
    // Effect (optional)
    effect: 'slide', // 'slide', 'fade', 'cube', 'coverflow', 'flip'
    
    // Responsive breakpoints
    breakpoints: {
        640: {
            slidesPerView: 1,
            spaceBetween: 0,
        },
        768: {
            slidesPerView: 1,
            spaceBetween: 0,
        },
        1024: {
            slidesPerView: 1,
            spaceBetween: 0,
        },
    },
    
    // Events
    on: {
        init: function () {
            console.log('Swiper initialized');
        },
        slideChange: function () {
            console.log('Slide changed to:', this.activeIndex);
        },
    },
});

// Additional controls
function pauseSlider() {
    swiper.autoplay.stop();
}

function resumeSlider() {
    swiper.autoplay.start();
}

function goToSlide(index) {
    swiper.slideTo(index);
}
</script>
Demo: Working Carousel with Pagination
Demo Image 1
Slide 1

Beautiful landscape

Demo Image 2
Slide 2

Amazing architecture

Demo Image 3
Slide 3

Nature photography

Demo Image 4
Slide 4

Urban landscape

Modal/Lightbox
<!-- SweetAlert2 for Beautiful Modals -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>

<!-- HTML Triggers -->
<button class="btn btn-primary" onclick="showSuccessAlert()">Success Alert</button>
<button class="btn btn-warning" onclick="showConfirmDialog()">Confirm Dialog</button>
<button class="btn btn-info" onclick="showInputDialog()">Input Dialog</button>

<script>
// Success alert
function showSuccessAlert() {
    Swal.fire({
        icon: 'success',
        title: 'Great!',
        text: 'Your action was successful!',
        timer: 2000,
        showConfirmButton: false
    });
}

// Confirmation dialog
function showConfirmDialog() {
    Swal.fire({
        title: 'Are you sure?',
        text: "You won't be able to revert this!",
        icon: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        confirmButtonText: 'Yes, delete it!'
    }).then((result) => {
        if (result.isConfirmed) {
            Swal.fire(
                'Deleted!',
                'Your file has been deleted.',
                'success'
            );
        }
    });
}

// Input dialog
async function showInputDialog() {
    const { value: email } = await Swal.fire({
        title: 'Input email address',
        input: 'email',
        inputLabel: 'Your email address',
        inputPlaceholder: 'Enter your email address',
        inputValidator: (value) => {
            if (!value) {
                return 'You need to write something!';
            }
        }
    });

    if (email) {
        Swal.fire(`Entered email: ${email}`);
    }
}

// Custom modal with HTML content
function showCustomModal() {
    Swal.fire({
        title: 'Custom HTML Content',
        html: `
            <div class="text-start">
                <h5>User Profile</h5>
                <form id="profileForm">
                    <div class="mb-3">
                        <label class="form-label">Name:</label>
                        <input type="text" class="form-control" id="userName">
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Email:</label>
                        <input type="email" class="form-control" id="userEmail">
                    </div>
                </form>
            </div>
        `,
        showCancelButton: true,
        confirmButtonText: 'Save Profile',
        preConfirm: () => {
            const name = document.getElementById('userName').value;
            const email = document.getElementById('userEmail').value;
            
            if (!name || !email) {
                Swal.showValidationMessage('Please fill all fields');
                return false;
            }
            
            return { name, email };
        }
    }).then((result) => {
        if (result.isConfirmed) {
            console.log('Profile data:', result.value);
        }
    });
}
</script>
Form Validation Library
Demo: Form Validation with Plugin

Praktik Unit 6: Dashboard dengan Bootstrap & Plugins

Tugas Praktik:
  1. Integrasikan Bootstrap untuk layout dashboard
  2. Tambahkan Chart.js untuk visualisasi data
  3. Implementasi date picker untuk filter
  4. Gunakan SweetAlert untuk konfirmasi actions
Template: Complete Dashboard
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard - Admin Panel</title>
    
    <!-- CSS Libraries -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
</head>
<body>
    <!-- Navigation -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="#">
                <i class="fas fa-tachometer-alt me-2"></i>Dashboard
            </a>
            <div class="navbar-nav ms-auto">
                <a class="nav-link" href="#">
                    <i class="fas fa-user me-1"></i>Admin
                </a>
            </div>
        </div>
    </nav>

    <div class="container-fluid">
        <div class="row">
            <!-- Sidebar -->
            <nav class="col-md-3 col-lg-2 d-md-block bg-light sidebar">
                <div class="position-sticky pt-3">
                    <ul class="nav flex-column">
                        <li class="nav-item">
                            <a class="nav-link active" href="#">
                                <i class="fas fa-home me-2"></i>Dashboard
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">
                                <i class="fas fa-users me-2"></i>Users
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">
                                <i class="fas fa-chart-bar me-2"></i>Analytics
                            </a>
                        </li>
                    </ul>
                </div>
            </nav>

            <!-- Main Content -->
            <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
                <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
                    <h1 class="h2">Dashboard</h1>
                    <div class="btn-toolbar mb-2 mb-md-0">
                        <input type="text" id="dateRange" class="form-control me-2" placeholder="Select date range">
                        <button class="btn btn-sm btn-outline-secondary" onclick="exportData()">
                            <i class="fas fa-download"></i> Export
                        </button>
                    </div>
                </div>

                <!-- Stats Cards -->
                <div class="row mb-4">
                    <div class="col-md-3">
                        <div class="card text-white bg-primary">
                            <div class="card-body">
                                <div class="d-flex justify-content-between">
                                    <div>
                                        <h4>1,234</h4>
                                        <p class="card-text">Total Users</p>
                                    </div>
                                    <div>
                                        <i class="fas fa-users fa-2x"></i>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <!-- Repeat for other stats -->
                </div>

                <!-- Charts -->
                <div class="row">
                    <div class="col-md-8">
                        <div class="card">
                            <div class="card-header">
                                <h5>Monthly Statistics</h5>
                            </div>
                            <div class="card-body">
                                <canvas id="monthlyChart"></canvas>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-4">
                        <div class="card">
                            <div class="card-header">
                                <h5>Distribution</h5>
                            </div>
                            <div class="card-body">
                                <canvas id="pieChart"></canvas>
                            </div>
                        </div>
                    </div>
                </div>
            </main>
        </div>
    </div>

    <!-- JavaScript Libraries -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
    
    <script>
        // Initialize date range picker
        flatpickr("#dateRange", {
            mode: "range",
            dateFormat: "Y-m-d"
        });

        // Initialize charts
        const monthlyCtx = document.getElementById('monthlyChart').getContext('2d');
        const monthlyChart = new Chart(monthlyCtx, {
            type: 'line',
            data: {
                labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
                datasets: [{
                    label: 'Users',
                    data: [12, 19, 3, 5, 2, 3],
                    borderColor: 'rgb(75, 192, 192)',
                    tension: 0.1
                }]
            }
        });

        function exportData() {
            Swal.fire({
                title: 'Export Data',
                text: 'Choose export format:',
                showCancelButton: true,
                confirmButtonText: 'Excel',
                cancelButtonText: 'PDF'
            });
        }
    </script>
</body>
</html>