Tailwind CSS 色を指定する

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Tailwind CSS</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body>
    <h1 class="text-center text-4xl font-bold text-red-500 opacity-50">Hello</h1>
</body>

</html>

ニコニコ動画風サイト

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ニコニコ動画風サイト</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
        }
        header {
            background-color: #333;
            color: #fff;
            padding: 10px 20px;
            text-align: center;
        }
        nav {
            background-color: #555;
            color: #fff;
            display: flex;
            justify-content: space-around;
            padding: 10px 0;
        }
        nav a {
            color: #fff;
            text-decoration: none;
            padding: 10px 20px;
        }
        main {
            display: flex;
            margin: 20px;
        }
        aside {
            width: 25%;
            background-color: #fff;
            padding: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        section {
            width: 75%;
            padding: 20px;
        }
        .video-player {
            background-color: #000;
            height: 400px;
            margin-bottom: 20px;
            position: relative;
        }
        .video-player video {
            width: 100%;
            height: 100%;
        }
        footer {
            background-color: #333;
            color: #fff;
            text-align: center;
            padding: 10px 0;
        }
        .comments {
            list-style: none;
            padding: 0;
        }
        .comments li {
            background-color: #fff;
            margin-bottom: 10px;
            padding: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        .comment-form {
            display: flex;
            margin-top: 20px;
        }
        .comment-form input {
            flex: 1;
            padding: 10px;
            margin-right: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .comment-form button {
            padding: 10px 20px;
            border: none;
            background-color: #333;
            color: #fff;
            border-radius: 5px;
            cursor: pointer;
        }
        .thumbnail {
            display: flex;
            align-items: center;
            margin-bottom: 20px;
        }
        .thumbnail img {
            width: 120px;
            height: 90px;
            margin-right: 10px;
        }
        .login-form, .register-form, .upload-form, .profile {
            background-color: #fff;
            padding: 20px;
            margin-bottom: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        .login-form h2, .register-form h2, .upload-form h2, .profile h2 {
            margin-top: 0;
        }
        .login-form input, .register-form input, .upload-form input {
            width: 100%;
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .login-form button, .register-form button, .upload-form button {
            width: 100%;
            padding: 10px;
            border: none;
            background-color: #333;
            color: #fff;
            border-radius: 5px;
            cursor: pointer;
        }
        .search-form {
            display: flex;
            justify-content: center;
            margin: 20px 0;
        }
        .search-form input {
            width: 70%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .search-form button {
            padding: 10px 20px;
            border: none;
            background-color: #333;
            color: #fff;
            border-radius: 5px;
            cursor: pointer;
        }
        .rating {
            display: flex;
            align-items: center;
            margin-top: 10px;
        }
        .rating button {
            border: none;
            background: none;
            cursor: pointer;
            font-size: 1.2em;
            margin-right: 10px;
        }
        .rating span {
            margin-right: 20px;
        }
    </style>
</head>
<body>
    <header>
        <h1>ニコニコ動画風サイト</h1>
    </header>
    <nav>
        <a href="index.html">ホーム</a>
        <a href="ranking.html">ランキング</a>
        <a href="categories.html">カテゴリー</a>
        <a href="mypage.html">マイページ</a>
    </nav>
    <div class="search-form">
        <input type="text" id="searchInput" placeholder="検索...">
        <button onclick="search()">検索</button>
    </div>
    <main>
        <aside>
            <h2>おすすめ動画</h2>
            <div class="thumbnail">
                <a href="video.html"><img src="thumbnail1.jpg" alt="動画1"></a>
                <a href="video.html">動画1のタイトル</a>
            </div>
            <div class="thumbnail">
                <a href="video.html"><img src="thumbnail2.jpg" alt="動画2"></a>
                <a href="video.html">動画2のタイトル</a>
            </div>
            <div class="thumbnail">
                <a href="video.html"><img src="thumbnail3.jpg" alt="動画3"></a>
                <a href="video.html">動画3のタイトル</a>
            </div>
            <div class="thumbnail">
                <a href="video.html"><img src="thumbnail4.jpg" alt="動画4"></a>
                <a href="video.html">動画4のタイトル</a>
            </div>
        </aside>
        <section>
            <div class="video-player">
                <video controls>
                    <source src="sample.mp4" type="video/mp4">
                    あなたのブラウザは動画タグに対応していません。
                </video>
            </div>
            <h2>動画タイトル</h2>
            <p>動画の説明文がここに入ります。</p>
            <div class="rating">
                <button onclick="like()">👍</button><span id="likeCount">0</span>
                <button onclick="dislike()">👎</button><span id="dislikeCount">0</span>
            </div>
            <h3>コメント</h3>
            <ul class="comments" id="comments">
                <li><span class="timestamp">12:34</span> コメント1</li>
                <li><span class="timestamp">12:35</span> コメント2</li>
                <li><span class="timestamp">12:36</span> コメント3</li>
                <li><span class="timestamp">12:37</span> コメント4</li>
            </ul>
            <div class="comment-form">
                <input type="text" id="commentInput" placeholder="コメントを入力してください">
                <button onclick="addComment()">コメントを投稿</button>
            </div>
        </section>
    </main>
    <footer>
    </footer>

    <!-- Register Form -->
    <div class="register-form">
        <h2>ユーザー登録</h2>
        <input type="text" id="registerUsername" placeholder="ユーザー名">
        <input type="password" id="registerPassword" placeholder="パスワード">
        <button onclick="register()">登録</button>
    </div>

    <!-- Login Form -->
    <div class="login-form">
        <h2>ログイン</h2>
        <input type="text" id="loginUsername" placeholder="ユーザー名">
        <input type="password" id="loginPassword" placeholder="パスワード">
        <button onclick="login()">ログイン</button>
    </div>

    <!-- Upload Form -->
    <div class="upload-form">
        <h2>動画アップロード</h2>
        <input type="file" id="uploadVideo">
        <input type="text" id="uploadTitle" placeholder="タイトル">
        <button onclick="upload()">アップロード</button>
    </div>

    <!-- Profile Page -->
    <div class="profile">
        <h2>プロフィール</h2>
        <p>ユーザー名: <span id="profileUsername"></span></p>
        <p>登録日: <span id="profileDate"></span></p>
    </div>

    <script>
        let likeCount = 0;
        let dislikeCount = 0;

        function addComment() {
            var commentInput = document.getElementById('commentInput');
            var commentText = commentInput.value.trim();
            if (commentText !== "") {
                var commentsList = document.getElementById('comments');
                var newComment = document.createElement('li');
                var timestamp = new Date().toLocaleTimeString();
                newComment.innerHTML = '<span class="timestamp">' + timestamp + '</span> ' + commentText;
                commentsList.appendChild(newComment);
                commentInput.value = "";
            }
        }

        function like() {
            likeCount++;
            document.getElementById('likeCount').innerText = likeCount;
        }

        function dislike() {
            dislikeCount++;
            document.getElementById('dislikeCount').innerText = dislikeCount;
        }

        function search() {
            var searchInput = document.getElementById('searchInput').value.trim();
            if (searchInput !== "") {
                alert('検索結果: ' + searchInput);
            }
        }

        function register() {
            var username = document.getElementById('registerUsername').value.trim();
            var password = document.getElementById('registerPassword').value.trim();
            if (username !== "" && password !== "") {
                alert('ユーザー登録が完了しました: ' + username);
                localStorage.setItem('username', username);
                localStorage.setItem('password', password);
                document.getElementById('registerUsername').value = "";
                document.getElementById('registerPassword').value = "";
            }
        }

        function login() {
            var username = document.getElementById('loginUsername').value.trim();
            var password = document.getElementById('loginPassword').value.trim();
            var storedUsername = localStorage.getItem('username');
            var storedPassword = localStorage.getItem('password');
            if (username === storedUsername && password === storedPassword) {
                alert('ログイン成功');
                document.getElementById('profileUsername').innerText = username;
                document.getElementById('profileDate').innerText = new Date().toLocaleDateString();
                document.getElementById('loginUsername').value = "";
                document.getElementById('loginPassword').value = "";
            } else {
                alert('ユーザー名またはパスワードが間違っています');
            }
        }

        function upload() {
            var video = document.getElementById('uploadVideo').files[0];
            var title = document.getElementById('uploadTitle').value.trim();
            if (video && title !== "") {
                alert('動画アップロードが完了しました: ' + title);
                document.getElementById('uploadVideo').value = "";
                document.getElementById('uploadTitle').value = "";
            }
        }
    </script>
</body>
</html>

TailwindCSS テキスト周りのスタイルを設定する

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Tailwind CSS</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body>
    <h1 class="text-center text-4xl font-bold">Hello</h1>
</body>

</html>

Tailwind CSS 拡張機能

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Tailwind CSS</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
  <h1 class="text-center">Hello</h1>
</body>
</html>

tailwind.config.js

CSS ローディングアイコン

index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Animation</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="loading"></div>
</body>

</html>

style.css

@charset "utf-8";

.loading{
    width: 32px;
    height: 32px;
    border-top: 8px solid red;
    border-right: 8px solid blue;
    border-bottom: 8px solid green;
    border-left: 8px solid yellow;
    border-radius: 50%;
    animation: spin 800ms infinite linear;
    /*animation-timing-function: linear;*/
}

@keyframes spin {
    100%{
        transform: rotate(360deg);
    }
}

python WEBブラウザ

import sys
import os
import json
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QLineEdit, QWidget, QTabWidget, QAction, QMenuBar, QMenu, QListWidget, QInputDialog, QMessageBox, QFileDialog, QToolBar)
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile, QWebEngineDownloadItem
from PyQt5.QtCore import QUrl, QTimer, Qt

class Browser(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Advanced Browser')
        self.setGeometry(100, 100, 1200, 800)
        
        self.bookmarks = []
        self.history = []
        self.home_page = 'http://www.google.com'
        self.auto_browse_url = ''
        self.auto_browse_interval = 60
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.auto_browse)

        self.load_settings()

        self.tab_widget = QTabWidget()
        self.tab_widget.setDocumentMode(True)
        self.tab_widget.tabBarDoubleClicked.connect(self.add_new_tab)
        self.tab_widget.currentChanged.connect(self.update_url_bar)
        self.tab_widget.setTabsClosable(True)
        self.tab_widget.tabCloseRequested.connect(self.close_current_tab)

        self.setCentralWidget(self.tab_widget)
        self.status = QLineEdit()
        self.status.setReadOnly(True)
        self.statusBar().addPermanentWidget(self.status)

        navtb = QToolBar("Navigation")
        self.addToolBar(navtb)

        self.url_bar = QLineEdit()
        self.url_bar.returnPressed.connect(self.navigate_to_url)

        self.back_button = QPushButton('<')
        self.back_button.clicked.connect(lambda: self.tab_widget.currentWidget().back())

        self.forward_button = QPushButton('>')
        self.forward_button.clicked.connect(lambda: self.tab_widget.currentWidget().forward())

        self.reload_button = QPushButton('R')
        self.reload_button.clicked.connect(lambda: self.tab_widget.currentWidget().reload())

        self.add_tab_button = QPushButton('+')
        self.add_tab_button.clicked.connect(self.add_new_tab)

        self.auto_browse_button = QPushButton('Auto Browse')
        self.auto_browse_button.clicked.connect(self.toggle_auto_browse)

        navtb.addWidget(self.back_button)
        navtb.addWidget(self.forward_button)
        navtb.addWidget(self.reload_button)
        navtb.addWidget(self.url_bar)
        navtb.addWidget(self.add_tab_button)
        navtb.addWidget(self.auto_browse_button)

        self.menu_bar = QMenuBar()
        self.setMenuBar(self.menu_bar)

        self.file_menu = QMenu("&File", self)
        self.menu_bar.addMenu(self.file_menu)

        self.bookmark_menu = QMenu("&Bookmarks", self)
        self.menu_bar.addMenu(self.bookmark_menu)
        self.bookmark_menu.addAction("Add Bookmark", self.add_bookmark)
        self.bookmark_menu.addAction("Show Bookmarks", self.show_bookmarks)

        self.history_menu = QMenu("&History", self)
        self.menu_bar.addMenu(self.history_menu)
        self.history_menu.addAction("Show History", self.show_history)
        
        self.settings_menu = QMenu("&Settings", self)
        self.menu_bar.addMenu(self.settings_menu)
        self.settings_menu.addAction("Set Home Page", self.set_home_page)
        self.settings_menu.addAction("Set Auto Browse", self.set_auto_browse)

        self.add_new_tab(QUrl(self.home_page), "Home")

    def add_new_tab(self, qurl=None, label="New Tab"):
        if qurl is None:
            qurl = QUrl(self.home_page)

        browser = QWebEngineView()
        browser.setUrl(qurl)
        i = self.tab_widget.addTab(browser, label)
        self.tab_widget.setCurrentIndex(i)

        browser.urlChanged.connect(lambda qurl, browser=browser: self.update_url(qurl, browser))
        browser.loadFinished.connect(lambda _, i=i, browser=browser: self.tab_widget.setTabText(i, browser.page().title()))
        browser.page().profile().downloadRequested.connect(self.download_requested)

    def update_url(self, qurl, browser=None):
        if browser != self.tab_widget.currentWidget():
            return
        self.url_bar.setText(qurl.toString())
        self.status.setText(qurl.toString())
        self.history.append(qurl.toString())

    def navigate_to_url(self):
        qurl = QUrl(self.url_bar.text())
        self.tab_widget.currentWidget().setUrl(qurl)

    def update_url_bar(self, i):
        qurl = self.tab_widget.currentWidget().url()
        self.url_bar.setText(qurl.toString())
        self.status.setText(qurl.toString())

    def close_current_tab(self, i):
        if self.tab_widget.count() < 2:
            return
        self.tab_widget.removeTab(i)

    def add_bookmark(self):
        url = self.url_bar.text()
        if url and url not in self.bookmarks:
            self.bookmarks.append(url)
            QMessageBox.information(self, "Bookmark Added", "Bookmark has been added.")
            self.save_settings()

    def show_bookmarks(self):
        dlg = QInputDialog(self)
        dlg.setLabelText("Bookmarks:")
        dlg.setComboBoxItems(self.bookmarks)
        dlg.exec_()

    def show_history(self):
        dlg = QInputDialog(self)
        dlg.setLabelText("History:")
        dlg.setComboBoxItems(self.history)
        dlg.exec_()

    def set_home_page(self):
        url, ok = QInputDialog.getText(self, "Set Home Page", "Enter URL:")
        if ok and url:
            self.home_page = url
            self.save_settings()

    def set_auto_browse(self):
        url, ok1 = QInputDialog.getText(self, "Set Auto Browse URL", "Enter URL:")
        if ok1 and url:
            interval, ok2 = QInputDialog.getInt(self, "Set Auto Browse Interval", "Enter Interval (seconds):", min=1)
            if ok2:
                self.auto_browse_url = url
                self.auto_browse_interval = interval
                self.save_settings()

    def toggle_auto_browse(self):
        if self.timer.isActive():
            self.timer.stop()
            self.auto_browse_button.setText("Auto Browse")
        else:
            self.timer.start(self.auto_browse_interval * 1000)
            self.auto_browse_button.setText("Stop Auto Browse")

    def auto_browse(self):
        if self.auto_browse_url:
            self.tab_widget.currentWidget().setUrl(QUrl(self.auto_browse_url))

    def download_requested(self, download):
        path, _ = QFileDialog.getSaveFileName(self, "Save File", download.path())
        if path:
            download.setPath(path)
            download.accept()

    def load_settings(self):
        if os.path.exists('browser_settings.json'):
            with open('browser_settings.json', 'r') as f:
                settings = json.load(f)
                self.bookmarks = settings.get('bookmarks', [])
                self.history = settings.get('history', [])
                self.home_page = settings.get('home_page', 'http://www.google.com')
                self.auto_browse_url = settings.get('auto_browse_url', '')
                self.auto_browse_interval = settings.get('auto_browse_interval', 60)

    def save_settings(self):
        settings = {
            'bookmarks': self.bookmarks,
            'history': self.history,
            'home_page': self.home_page,
            'auto_browse_url': self.auto_browse_url,
            'auto_browse_interval': self.auto_browse_interval
        }
        with open('browser_settings.json', 'w') as f:
            json.dump(settings, f)

app = QApplication(sys.argv)
app.setApplicationName("Advanced Browser")
window = Browser()
window.show()
sys.exit(app.exec_())

ECサイトGamazon

http://tyosuke20xx.com/Gamazon.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Gamazon</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .navbar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 1rem;
            background-color: #131921;
            color: white;
        }
        .navbar h1 {
            font-size: 1.5rem;
        }
        .navbar nav ul {
            list-style: none;
            display: flex;
        }
        .navbar nav ul li {
            padding: 0 10px;
        }
        .navbar nav ul li a {
            text-decoration: none;
            color: white;
        }
        .product {
            border: 1px solid #ccc;
            margin: 10px;
            padding: 10px;
            width: 200px;
            float: left;
        }
        .product img {
            width: 100%;
            height: auto;
        }
        .featured-products .carousel {
            display: flex;
            overflow-x: auto;
            scroll-snap-type: x mandatory;
        }
        .featured-products .carousel div {
            scroll-snap-align: start;
            flex: 0 0 90%;
            margin-right: 10px;
        }
    </style>
</head>
<body>
    <header>
        <div class="navbar">
            <h1>My Gmazon Store</h1>
            <input type="text" placeholder="商品を検索" id="search-box">
            <button onclick="searchProduct()">検索</button>
            <nav>
                <ul>
                    <li><a href="#">ホーム</a></li>
                    <li><a href="#">商品カテゴリ</a></li>
                    <li><a href="#">セール</a></li>
                    <li><a href="#">お問い合わせ</a></li>
                </ul>
            </nav>
        </div>
    </header>

    <main>
        <section class="featured-products">
            <h2>特選商品</h2>
            <div class="carousel">
                <!-- カルーセル用のJavaScriptで動的に商品を挿入 -->
            </div>
        </section>

        <section class="product-list">
            <h2>商品リスト</h2>
            <div class="products">
                <!-- 商品リスト -->
            </div>
        </section>

        <section class="customer-reviews">
            <h2>ユーザーレビュー</h2>
            <div class="reviews">
                <!-- レビュー -->
            </div>
        </section>
    </main>

    <footer>
        <p>© 2024 My Gmazon Store. All rights reserved.</p>
    </footer>

    <script>
        function searchProduct() {
            const searchInput = document.getElementById('search-box').value;
            alert('検索した商品: ' + searchInput);
        }

        // 他にもカルーセルの動きやユーザーレビューを動的に表示する関数を追加
    </script>
</body>
</html>

Pinterest風サイト

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pintrest風サイト</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f0f0f0;
        }

        header {
            background-color: #333;
            color: #fff;
            padding: 20px;
            text-align: center;
        }

        .container {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
            gap: 20px;
            padding: 20px;
            margin: 0 auto;
            max-width: 1200px;
        }

        .card {
            background-color: #fff;
            border: 1px solid #ddd;
            border-radius: 5px;
            overflow: hidden;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            transition: transform 0.3s ease;
            cursor: pointer;
        }

        .card:hover {
            transform: translateY(-5px);
        }

        .card img {
            width: 100%;
            display: block;
            border-top-left-radius: 5px;
            border-top-right-radius: 5px;
        }

        .card-content {
            padding: 15px;
        }

        .card h2 {
            font-size: 18px;
            margin: 10px 0;
            color: #333;
        }

        .card p {
            font-size: 14px;
            color: #666;
            margin-top: 0;
        }

        .modal {
            display: none;
            position: fixed;
            z-index: 999;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.7);
        }

        .modal-content {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: #fff;
            padding: 20px;
            border-radius: 5px;
        }

        .modal img {
            max-width: 100%;
            display: block;
            margin: 0 auto;
        }

        footer {
            background-color: #333;
            color: #fff;
            text-align: center;
            padding: 10px 0;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <header>
        <h1>Pintrest風サイト</h1>
    </header>

    <main>
        <div class="container">
            <div class="card" onclick="openModal('https://via.placeholder.com/800x600', 'Beautiful Sunset', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.')">
                <img src="https://via.placeholder.com/400x250" alt="Image 1">
                <div class="card-content">
                    <h2>Beautiful Sunset</h2>
                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
                </div>
            </div>
            <div class="card" onclick="openModal('https://via.placeholder.com/800x600', 'Cute Kittens', 'Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.')">
                <img src="https://via.placeholder.com/400x300" alt="Image 2">
                <div class="card-content">
                    <h2>Cute Kittens</h2>
                    <p>Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.</p>
                </div>
            </div>
            <!-- More cards -->
        </div>
    </main>

    <div id="myModal" class="modal">
        <div class="modal-content">
            <span class="close" onclick="closeModal()">&times;</span>
            <img src="" alt="Modal Image" id="modalImage">
            <div id="caption"></div>
        </div>
    </div>

    <footer>
        <p>&copy; 2024 Pintrest風サイト</p>
    </footer>

    <script>
        function openModal(imageSrc, title, description) {
            document.getElementById("modalImage").src = imageSrc;
            document.getElementById("caption").innerHTML = "<h2>" + title + "</h2><p>" + description + "</p>";
            document.getElementById("myModal").style.display = "block";
        }

        function closeModal() {
            document.getElementById("myModal").style.display = "none";
        }
    </script>
</body>
</html>

Slack風チャットボットサイト

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Slack風チャットボット</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
        }

        .chat-container {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }

        .chat-window {
            width: 400px;
            background-color: #f4f4f4;
            border: 1px solid #ddd;
            border-radius: 5px;
            padding: 20px;
        }

        .chat-messages {
            height: 300px;
            overflow-y: auto;
            border-bottom: 1px solid #ddd;
            margin-bottom: 10px;
        }

        #message-input {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            margin-bottom: 10px;
        }

        button {
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        button:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>
    <div class="chat-container">
        <div class="chat-window">
            <div class="chat-messages" id="chat-messages">
                <!-- チャットメッセージが表示される部分 -->
            </div>
            <input type="text" id="message-input" placeholder="メッセージを入力してください...">
            <button onclick="sendMessage()">送信</button>
        </div>
    </div>

    <script>
        function sendMessage() {
            var messageInput = document.getElementById('message-input');
            var message = messageInput.value.trim();

            if (message !== '') {
                var chatMessages = document.getElementById('chat-messages');
                var messageElement = document.createElement('div');
                messageElement.textContent = message;
                chatMessages.appendChild(messageElement);
                messageInput.value = '';

                // メッセージをバックエンドに送信
                fetch('/send_message', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ message: message })
                });
            }
        }
    </script>
</body>
</html>

Ruby on Rails Todoリスト

Ruby on Railsを使用してTodoリストを作成する方法を説明します。まずは、以下の手順に従って新しいRailsアプリケーションを作成しましょう。

  1. ターミナルを開いて、プロジェクトを保存するディレクトリに移動します。
  2. 次のコマンドを実行して、新しいRailsアプリケーションを作成します。

rails new todo_list

  1. 作成したディレクトリに移動します。

cd todo_list

次に、Todoリストの機能を追加します。

  1. Todoアイテムを保存するためのデータモデルを作成します。

rails generate model TodoItem title:string description:text completed:boolean

  1. データベースにマイグレーションを実行して、新しいテーブルを作成します。

rails db:migrate

  1. Todoアイテムを操作するためのコントローラーを作成します。

rails generate controller TodoItems

  1. config/routes.rb ファイルを開き、以下のようにルートを設定します。

Rails.application.routes.draw do resources :todo_items root 'todo_items#index' end

  1. app/controllers/todo_items_controller.rb ファイルを開いて、アクションを追加します。

class TodoItemsController < ApplicationController before_action :set_todo_item, only: [:show, :edit, :update, :destroy] def index @todo_items = TodoItem.all end def show end def new @todo_item = TodoItem.new end def edit end def create @todo_item = TodoItem.new(todo_item_params) if @todo_item.save redirect_to @todo_item, notice: 'Todo item was successfully created.' else render :new end end def update if @todo_item.update(todo_item_params) redirect_to @todo_item, notice: 'Todo item was successfully updated.' else render :edit end end def destroy @todo_item.destroy redirect_to todo_items_url, notice: 'Todo item was successfully destroyed.' end private def set_todo_item @todo_item = TodoItem.find(params[:id]) end def todo_item_params params.require(:todo_item).permit(:title, :description, :completed) end end

  1. app/views/todo_items ディレクトリ内に、必要なビューファイル(index、show、new、edit)を作成します。
  2. app/views/todo_items/index.html.erb ファイルを開いて、Todoアイテムのリストを表示するコードを追加します。

<h1>Todo Items</h1> <%= link_to 'New Todo Item', new_todo_item_path %> <ul> <% @todo_items.each do |todo_item| %> <li> <%= link_to todo_item.title, todo_item %> <% if todo_item.completed %> (Completed) <% else %> (Pending) <% end %> </li> <% end %> </ul>

これで、基本的なTodoリストアプリケーションが完成しました。 rails server コマンドを使用してRailsサーバーを起動し、 http://localhost:3000/todo_items にアクセスしてアプリケーションを確認できます。

User

You

No template for interactive request TodoItemsController#new is missing a template for request formats: text/html NOTE! Unless told otherwise, Rails expects an action to render a template with the same name, contained in a folder named after its controller. If this controller is an API responding with 204 (No Content), which does not require a template, then this error will occur when trying to access it via browser, since we expect an HTML template to be rendered for such requests. If that’s the case, carry on. ChatGPT

ChatGPT

このエラーは、TodoItemsController#new アクションに対応するビューテンプレートが見つからないために発生しています。Railsは通常、コントローラーと同じ名前のフォルダ内にある同じ名前のビューテンプレートを期待します。

解決するためには、app/views/todo_items ディレクトリ内に new.html.erb という名前のビューテンプレートファイルを作成する必要があります。その後、新しいTodoアイテムを作成するためのフォームをこのファイルに追加します。

例えば、次のようなフォームを追加できます。

erbCopy code

<!-- app/views/todo_items/new.html.erb --> <h1>New Todo Item</h1> <%= form_with(model: @todo_item, url: todo_items_path) do |form| %> <%= form.label :title %> <%= form.text_field :title %> <%= form.label :description %> <%= form.text_area :description %> <%= form.submit 'Create Todo Item' %> <% end %> <%= link_to 'Back', todo_items_path %>

これで、TodoItemsController#new アクションに対するビューテンプレートが追加されました。再度ブラウザでアクセスすると、エラーは解消されるはずです。