Roa run dev

HTML+CSS+JavaScriptで「お問い合わせフォーム」ページ制作【レシピ】

●目次

    HTML+CSS+JavaScript【トップページ制作編】の続きの記事になります。

    ディレクトリ構成

    このディレクトリ構成は、Roa run devコードルールに従っています。

    ディレクトリ構成
    project-root/
    │
    ├── index.html         
    ├── contact.html 
    ├── style.css                
    │
    └── asset/
        ├── css/
        │   ├── reset.css        
        │   ├── layout.css       
        │   └── component.css    
        │
        ├── js/
        │   └── layout.js        
        │   └── component.js 
        │
        └── images/ 
    • index.html: トップページのHTMLファイル。
    • style.css: ページ全体のスタイルを定義したファイル。
    • reset.css: ブラウザごとのスタイルの違いをリセットするためのCSS。
      • デフォルトのCSSリセット
    • layout.css: ページのレイアウトに関連するスタイル。
      • ヘッダーやフッターのスタイリング
      • ボディーやメイン、セクション関連のスタイリング
    • component.css: ページのコンポーネントごとのスタイル。
      • ハンバーガナビなどのナビやページネーションなども含める
      • タブスライダーなどのアニメーションを持ったUIなど
    • layout.js: ページの動的要素やインタラクションを制御するJavaScriptファイル。

    HTML

    contact.htmlのform部分

    HTML(contact.html)
    <section class="section">
      <h2 class="heading02">お問い合わせフォーム</h2>
      <form id="contact-form" class="contactForm" action="submit.php" method="POST">
        <div class="formGroup">
          <label for="name">お名前:</label>
          <input type="text" class="inputText" id="name" name="name" required>
        </div>
        <div class="formGroup">
          <label for="email">メールアドレス:</label>
          <input type="email" class="inputText" id="email" name="email" required>
        </div>
        <div class="formGroup">
          <label for="phone">電話番号:</label>
          <input type="tel" class="inputText" id="phone" name="phone" pattern="\d{3}-\d{4}-\d{4}" placeholder="000-0000-0000">
        </div>
        <div class="formGroup">
          <label for="subject">件名:</label>
          <select class="select" id="subject"  name="subject" required>
            <option value="">選択してください</option>
            <option value="service">サービスについて</option>
            <option value="support">サポートについて</option>
            <option value="other">その他</option>
          </select>
        </div>
        <div class="formGroup">
          <label for="message">メッセージ:</label>
          <textarea class="textarea" id="message" name="message" rows="5" required></textarea>
        </div>
        <div class="formGroup">
          <label for="privacyPolicy">
            <input type="checkbox" class="checkbox" id="privacyPolicy" name="privacyPolicy" required>
          </label>
        </div>
        <button class="contactFormSubmit" type="submit">送信する</button>
      </form>
    </section>

    CSS

    component.cssのform関連一部

    CSS(component.css)
    /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
      お問い合わせフォーム
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
    .contactForm {
      width: 100%;
    }
    .formGroup {
      margin-bottom: 15px;
      padding: 10px;
      background-color: #fff;
    }
    
    /* フォーム-アイテム */
    .label {
      display: block;
      padding: 10px;
      border: 1px solid #000;
      background-color: #000;
      color: #fff;
      font-weight: 600;
    }
    .label-privacy {
      display: flex;
      justify-content: center;
      align-items: center;
      border: none;
      margin-top: 10px;
    }
    label-privacy input[type="checkbox"] {
      width: 30px;
      height: 30px;
    }
    /*  */
    input[type="text"],
    input[type="submit"],
    button[type="submit"]
    select,
    textarea {
      display: block;
      font-size: 16px;
    }
    input:focus,
    textarea:focus,
    select:focus,
    button:focus {
      outline: #ccc;
      border-color: #ccc; 
      box-shadow: none;
    }
    input[type="checkbox"]  {
      outline: #000;
      border:3px solid #000; 
    }
    /*  */
    .inputBox {
      width: 100%;
      padding: 10px;
      outline: #000;
      border: 3px solid #000; 
    }
    .textareaBox {
      width: 100%;
      height: 200px;
      padding: 10px;
      outline: #000;
      border:3px solid #000; 
    }
    .selectBox {
      width: 100%;
      padding: 10px;
      outline: #000;
      border: 3px solid #000; 
    }
    .checkbox {
      outline: #000;
      border:3px solid #000; 
      width: 30px;
      height: 30px;
    }
    button.contactFormSubmit {
      max-width: 250px;
      width: 100%;
      padding: 10px;
      background-color: #007bff;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }
    button.contactFormSubmit:hover {
      background-color: #0056b3;
    }
    
    /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
      お問い合わせ-スクロールボックス
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
    .contact-scroll-box {
      max-width: 760px;
      width: 100%;
      height: 300px;
      margin: 30px auto 0;
      padding: 30px 15px;
      background-color: #fff;
      border: 1px solid #ccc;
      color: #000;
      overflow-y: scroll;
    }
    .contact-scroll-box h3
    {
      font-size: 16px;
      font-weight: 700;
      line-height: 1em;
    }
    .contact-scroll-box ol {
      padding-left: 20px;
      list-style: decimal;
    }
    .contact-scroll-box ol li {
      font-size: 15px;
      line-height: 1.5em;
      font-weight: 400;
      margin-top: 30px;
      counter-increment: number;
    }
    .contact-scroll-box ol ol {
      font-size: 14px;
      line-height: 1.5em;
      font-weight: 300;
      margin-top: 15px;
      padding-left: 20px;
      list-style: none;
      counter-reset: number;
    }
    /*★★★min-width 768★★★*/
    @media screen and (min-width: 768px) {
      .contact-scroll-box h3
      {
        font-size: 18px;
        font-weight: 700;
      }
      .contact-scroll-box ol li {
        font-size: 16px;
      }
      .contact-scroll-box ol ol {
        font-size: 14px;
      }
    }
    

    JS

    component.jsのformの一部

    JavaScript(component.js)
    document.getElementById('contact-form').addEventListener('submit', function(event) {
      event.preventDefault();
    
      const name = document.getElementById('name').value.trim();
      const email = document.getElementById('email').value.trim();
      const phone = document.getElementById('phone').value.trim();
      const subject = document.getElementById('subject').value;
      const message = document.getElementById('message').value.trim();
      const privacyPolicy = document.getElementById('privacyPolicy').checked;
    
      let hasError = false;
      clearErrors();
    
      // バリデーション
      if (name === "") {
        setError('name', 'お名前を入力してください。');
        hasError = true;
      }
    
      if (!/^[\w\-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(email)) {
        setError('email', '有効なメールアドレスを入力してください。');
        hasError = true;
      }
    
      if (!hasError) {
        alert('フォームが送信されました!');
      }
    });
    
    function setError(id, message) {
      const element = document.getElementById(id);
      const errorElement = document.createElement('p');
      errorElement.className = 'error-message';
      errorElement.textContent = message;
      element.parentElement.appendChild(errorElement);
    }
    
    function clearErrors() {
      const errors = document.querySelectorAll('.error-message');
      errors.forEach(error => error.remove());
    }
    

    まとめ