Listing
One of the most common tasks in web development is displaying data from your database. SØAD makes this simple with ActiveJDBC models and Handlebars templates. This beginner-friendly recipe shows you how to fetch and display data in various ways.
Simple Data Listing
| book_list.py | |
|---|---|
CREATE TABLE book (
id int NOT NULL AUTO_INCREMENT,
title varchar(200) NOT NULL,
author varchar(100) NOT NULL,
genre varchar(50),
pages int,
year_published int,
created_at timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
INSERT INTO book (title, author, genre, pages, year_published) VALUES
('To Kill a Mockingbird', 'Harper Lee', 'Fiction', 281, 1960),
('1984', 'George Orwell', 'Dystopian Fiction', 328, 1949),
('Pride and Prejudice', 'Jane Austen', 'Romance', 279, 1813),
('The Great Gatsby', 'F. Scott Fitzgerald', 'Classic', 180, 1925),
('Harry Potter and the Sorcerer\'s Stone', 'J.K. Rowling', 'Fantasy', 309, 1997),
('The Lord of the Rings', 'J.R.R. Tolkien', 'Fantasy', 1216, 1954),
('The Catcher in the Rye', 'J.D. Salinger', 'Coming-of-age', 234, 1951),
('Brave New World', 'Aldous Huxley', 'Science Fiction', 268, 1932);
How It Works
- Fetch Data:
Book.findAll()gets all books from the database - Pass to Template:
ctx.output["books"] = booksmakes data available in the view - Display Data: Handlebars
{{#each books}}loops through each book - Show Fields:
{{title}},{{author}}display individual book properties
Ordered Listing
CREATE TABLE student (
id int NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
age int,
grade decimal(5,2),
subject varchar(50),
email varchar(150),
created_at timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
INSERT INTO student (name, age, grade, subject, email) VALUES
('Alice Johnson', 20, 85.5, 'Computer Science', '[email protected]'),
('Bob Smith', 19, 92.0, 'Mathematics', '[email protected]'),
('Carol Davis', 21, 78.5, 'Physics', '[email protected]'),
('David Wilson', 20, 88.0, 'Chemistry', '[email protected]'),
('Emma Brown', 19, 95.5, 'Biology', '[email protected]'),
('Frank Miller', 22, 82.0, 'History', '[email protected]'),
('Grace Lee', 20, 90.5, 'English', '[email protected]'),
('Henry Taylor', 19, 87.0, 'Art', '[email protected]');
Key Features
- Sorting:
orderBy("name ASC")sorts data before displaying - Multiple Sort Options: Different sorting methods in different actions
- Table Display: Clean table layout for structured data
- Conditional Display: Show different content based on data availability
Filtered Listing
CREATE TABLE product (
id int NOT NULL AUTO_INCREMENT,
name varchar(200) NOT NULL,
description text,
category varchar(50),
price decimal(10,2),
stock int DEFAULT 0,
created_at timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_category (category),
KEY idx_price (price)
);
INSERT INTO product (name, description, category, price, stock) VALUES
('Laptop Computer', 'High-performance laptop for work and gaming', 'Electronics', 899.99, 15),
('Wireless Mouse', 'Ergonomic wireless mouse with long battery life', 'Electronics', 29.99, 50),
('Programming Book', 'Learn Python programming from basics to advanced', 'Books', 39.99, 25),
('Smartphone', 'Latest model smartphone with great camera', 'Electronics', 699.99, 8),
('Cookbook', 'Delicious recipes for everyday cooking', 'Books', 24.99, 30),
('Tablet', 'Lightweight tablet perfect for reading and browsing', 'Electronics', 299.99, 12),
('Novel', 'Bestselling fiction novel', 'Books', 14.99, 40),
('Headphones', 'Noise-canceling wireless headphones', 'Electronics', 199.99, 20),
('Textbook', 'University-level mathematics textbook', 'Books', 89.99, 10),
('Phone Case', 'Protective case for smartphones', 'Electronics', 19.99, 100);
Filtering Features
- Category Filtering:
where("category = ?", "Electronics")filters by category - Price Filtering:
where("price < ?", 50.00)filters by price range - Navigation: Easy switching between different filters
- Dynamic Titles: Page title changes based on current filter
Limited Listing (Recent Items)
CREATE TABLE post (
id int NOT NULL AUTO_INCREMENT,
title varchar(200) NOT NULL,
excerpt text,
content longtext,
author varchar(100),
category varchar(50),
created_at timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_created (created_at)
);
INSERT INTO post (title, excerpt, content, author, category) VALUES
('Getting Started with Web Development', 'Learn the basics of building websites...', 'Complete guide to web development fundamentals...', 'John Developer', 'Tutorial'),
('Database Design Best Practices', 'Essential tips for designing efficient databases...', 'Comprehensive guide to database design patterns...', 'Jane DBA', 'Database'),
('JavaScript Tips and Tricks', 'Improve your JavaScript skills with these tips...', 'Advanced JavaScript techniques and patterns...', 'Mike Coder', 'Programming'),
('CSS Grid Layout Guide', 'Master CSS Grid for modern web layouts...', 'Complete tutorial on CSS Grid system...', 'Sarah Designer', 'CSS'),
('API Development with REST', 'Building robust REST APIs for web applications...', 'Step-by-step guide to REST API development...', 'Tom Architect', 'API'),
('Python for Beginners', 'Start your Python programming journey...', 'Introduction to Python programming language...', 'Lisa Teacher', 'Python'),
('Mobile App Development', 'Creating apps for iOS and Android...', 'Guide to cross-platform mobile development...', 'Alex Mobile', 'Mobile'),
('Security Best Practices', 'Keep your applications secure...', 'Essential security practices for web developers...', 'David Security', 'Security');
Limiting Features
- Limited Results:
limit(5)shows only the 5 most recent items - Count Display: Show total vs displayed count
- View Toggle: Switch between limited and full view
- Chronological Order:
orderBy("created_at DESC")shows newest first
Key Takeaways
findAll()gets all records from a tableorderBy()sorts the results (ASC = ascending, DESC = descending)where()filters records based on conditionslimit()restricts the number of results returnedctx.output["key"]passes data from transaction to template{{#each}}loops through data in Handlebars templates