فرم‌های HTML کامپوننت‌های ضروری برای اکثر وب‌سایت‌ها و برنامه‌های وب هستند. آن‌ها تعامل بین کاربران و وب‌سایت‌ها را امکان‌پذیر می‌کنند و یک مفهوم کلیدی برای توسعه‌دهندگان وب به شمار می‌آیند. در این مقاله قصد داریم تا جنبه‌های مختلف فرم‌های HTML از جمله نحوه ایجاد آن‌ها، ساختار فرم‌ها، روش تعامل جاوااسکریپت، مدیریت فرم و همینطور اعتبارسنجی فرم را بررسی کنیم. همچنین با بررسی مثال‌های واقعی، به درک درست درمورد ایجاد فرم‌های وب قوی که تجربه کاربری را افزایش می‌دهند و جمع‌آوری و ارسال یکپارچه داده‌ها فراهم می‌کنند، دست پیدا خواهیم کرد.

درک نحوه کار فرم HTML این امکان را به ما می‌دهد تا مقادیر input که توسط کاربر وارد می‌شود را به کمک جاوااسکریپت اعتبارسنجی کنیم، موارد ارسالی را مدیریت کرده و به طور کلی تجربه کاربری را بهبود ببخشیم.

آشنایی با فرم‌های HTML

فرم‌های HTML المنت‌های اساسی هستند که برای جمع‌آوری و ارسال داده‌های کاربر در وب مورد استفاده قرار می‌گیرند. این فرم‌ها شرایطی را فراهم می‌کنند تا کاربران بتوانند اطلاعات خود را در سایت وارد کنند و داده‌ها را برای پردازش به سمت سرور ارسال نمایند. به این ترتیب می‌توانند یک تعامل خوب با وب‌سایت‌ها داشته باشند.

مقدمه‌ای بر المنت‌های فرم HTML

فرم‌های HTML با استفاده از المنت <form> ایجاد می‌شوند که به عنوان یک container برای المنت‌های input مختلف عمل می‌کند. المنت‌های فرم رایج شامل فیلدهای متنی، checkboxeها، radio buttonها، منوهای dropdown و دکمه‌ها می‌باشند.

ارجاع به فرم در جاوااسکریپت را می‌توانیم با استفاده از متدهای DOM مانند getElementById() یا document.forms مدیریت کنیم. document.forms مجموعه‌ای از فرم‌ها را return می‌کند و ما می‌توانیم با استفاده از یک index، name یا id به یک فرم خاص دسترسی داشته باشیم.

const form = document.getElementById('signup');
const firstForm = document.forms[0]; // accessing first form
const formByName = document.forms['formName']; // accessing form by name
const formById = document.forms['formId']; // accessing form by id

به عنوان مثال:

<form>
  <label for="username">Username:</label>
  <input type="text" id="username" name="username"><br>

  <label for="password">Password:</label>
  <input type="password" id="password" name="password"><br>

  <input type="submit" value="Submit">
</form>

در قطعه کد بالا که یک مثال بیسیک از فرم‌های HTML است، یک فرم با دو فیلد ورودی برای نام کاربری و رمز عبور به همراه یک دکمه برای ارسال اطلاعات داریم.

ساختار فرم و ویژگی‌های آن

فرم‌های HTML می‌توانند ویژگی‌های مختلفی داشته باشند که رفتار و ظاهر آن‌ها را کنترل می‌کند. برخی از این ویژگی‌های رایج عبارتند از:

در ادامه مثالی از فرم با ویژگی‌هایی که درمورد آن‌ها صحبت کردیم را داریم:

<form action="/submit-form" method="POST" name="myForm" target="_blank">
  <!-- Form elements go here -->
</form&gt;

جاوااسکریپت و مدیریت فرم

جاوااسکریپت از آبجکت HTMLFormElement برای نمایش فرم استفاده می‌کند. این آبجکت دارای ویژگی‌های مربوط به action و method از ویژگی‌های HTML است.

متدهایی مانند submit() و reset() برای ارسال و تنظیم مجدد فرم‌ها مورد استفاده قرار می‌گیرند.

const form = document.getElementById('signup');
form.action; // returns the action attribute
form.method; // returns the method attribute
form.submit(); // submits the form

جاوااسکریپت Event Handlerهایی را فراهم می‌کند تا تعامل کاربران را به فرم های HTML اضافه نماید. با استفاده از این eventها، می‌توانیم اسکریپت‌های سفارشی را در پاسخ به اقدامات کاربر در فرم اجرا کنیم.

Submit Event: یک فرم معمولا دارای یک دکمه ارسال است که با کلیک بر روی آن، داده‌های فرم را به سرور ارسال می‌کند. این مفهوم، با استفاده از المنت <input> یا <button> همراه با type="submit" به دست می‌آید.

<input type="submit" value="Sign Up">
// or
<button type="submit">Sign Up</button>

برای این که یک event listener را به submit event پیوست کنیم، از متد addEventListener() استفاده می‌نماییم. به عنوان مثال:

const form = document.getElementById('signup');
form.addEventListener('submit', (event) => {
    // Custom validation and submission logic here
});

در بسیاری از موارد، ممکن است بخواهیم رفتار پیش‌فرض ارسال فرم را رهگیری کنیم و یک منطق سفارشی را، قبل از اینکه اجازه دهیم فرم به سرور ارسال شود اجرا نماییم. برای این کار می‌توانیم از preventDefault() استفاده کنیم. مثلا:

const form = document.getElementById('signup');
form.addEventListener('submit', (event) => {
    event.preventDefault(); // Prevents the default form submission
    // Custom validation and submission logic here
});

بدون event.preventDefault()، هرگونه اعتبارسنجی سفارشی و منطق ارسال همچنان در event listener اجرا می‌شود، اما از رفتار پیش‌فرض ارسال فرم جلوگیری صورت نمی‌گیرد.

Reset Event: این event زمانی فعال می‌شود که ما فرم را با استفاده از دکمه reset یا به صورت برنامه‌ریزی شده، reset کنیم. برای این که تمام فیلدهای فرم را پاک کنیم و مقادیر آن‌ها را بر روی مقادیر پیش‌فرض reset کنیم از متد reset() استفاده می‌نماییم.

document.querySelector('form').addEventListener('reset', function(event) {
    // Custom form reset logic here
});

نحوه دسترسی به فیلدهای فرم

ما می‌توانیم با استفاده از متدهای DOM مانند getElementsByName()، getElementById()، querySelector() و غیره به فیلدهای فرم دسترسی داشته باشیم.

ویژگی form.elements مجموعه‌ای از المنت‌های فرم را ذخیره می‌کند. ما می‌توانیم با index، id یا name به این المنت‌ها دسترسی داشته باشیم. به عنوان مثال:

const form = document.getElementById('signup');
const nameField = form.elements['name']; // accessing element by name
const emailField = form.elements['email']; // accessing element by name
const firstElement = form.elements[0]; // accessing first element by index no.

هنگامی که به یک فیلد فرم دسترسی پیدا کردیم، می‌توانید از ویژگی value برای دسترسی به مقدار آن استفاده نماییم. مثلا:

const nameValue = nameField.value;
const emailValue = emailFieldByName.value;

اعتبارسنجی فرم

اعتبارسنجی فرم یکی از جنبه‌های ضروری توسعه وب است. زیرا، تضمین می‌کند که داده‌های ارسال شده توسط کاربران قبل از پردازش توسط سرور، مطابق با معیارهای مشخص شده هستند. اعتبارسنجی‌های رایج شامل بررسی فیلدهای خالی، قالب‌های ایمیل معتبر و غیره می‌باشند.

اعتبارسنجی فرم HTML

HTML5 اعتبارسنجی داخلی فرم را از طریق ویژگی‌های مختلف فراهم می‌کند:

در ادامه نمونه‌ای از اعتبارسنجی فرم HTML داریم که از ویژگی‌های بالا در آن استفاده کرده‌ایم:

<form>
  <label for="username">Username:</label>
  <input type="text" id="username" name="username" required minlength="3" maxlength="15"><br>

  <label for="email">Email:</label>
  <input type="email" id="email" name="email" required><br>

  <label for="age">Age:</label>
  <input type="number" id="age" name="age" min="18" max="99"><br>

  <input type="submit" value="Submit">
</form>

در این مثال، فیلد username باید بین ۳ تا ۱۵ کاراکتر داشته باشد، فیلد email باید با فرمت صحیح پر شده و age باید بین ۱۸ تا ۹۹ سال باشد.

اعتبار سنجی فرم با جاوااسکریپت

جاوااسکریپت به توسعه‌دهندگان اجازه می‌دهد تا منطق اعتبارسنجی پیچیده‌تری را فراتر از آنچه که ویژگی‌های HTML ارائه می‌دهند، انجام دهند. می‌توانیم Event listenerها را به المنت‌های فرم تخصیص دهیم تا اعتبارسنجی به شکل داینامیک انجام شود. به عنوان مثال:

const form = document.querySelector('form');

form.addEventListener('submit', function(event) {
    event.preventDefault(); // Prevent form submission

    // Perform custom validation logic
    const email = document.getElementById('email').value;
    const password = document.getElementById('password').value;

    if (!emailIsValid(email)) {
        alert('Please enter a valid email address.');
        return;
    }

    if (password.length < 6) {
        alert('Password must be at least 6 characters long.');
        return;
    }

    // If validation passes, submit the form
    form.submit();
});

function emailIsValid(email) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

در این مثال، تابع جاوااسکریپتی emailIsValid() از یک عبارت regular برای اعتبارسنجی قالب ایمیل استفاده می‌کند. سپس در صورت عدم موفقیت در اعتبارسنجی، event listener مربوط به submit از ارسال فرم جلوگیری می‌کند و یک پیام خطای سفارشی به کاربر نشان می‌دهد.

بررسی فرم ثبت‌نام با یک مثال

در این بخش قصد داریم تا تمام مفاهیمی که در مورد مدیریت فرم آشنا شدیم را در یک مثال کامل از یک فرم ثبت‌نام با اعتبارسنجی سمت کلاینت با استفاده از جاوااسکریپت بررسی کنیم:

<!DOCTYPE html>
<html>
  <body>
    <h2>User Registration</h2>
    <form id="registrationForm">
      <div>
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" />
      </div>
      <div>
        <label for="email">Email:</label>
        <input type="email" id="email" name="email" />
      </div>
      <div>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" />
      </div>
      <div>
        <input type="submit" value="Register" />
      </div>
    </form>

    <div id="errorMessages"></div>
    <script src="script.js"></script>
  </body>
</html>

ساختار HTML: ما یک فرم ثبت نام ساده با فیلدهای username، email، password و دکمه ارسال داریم. همچنین یک div کانتینر (errorMessages) برای نمایش پیام‌های خطای مربوط به اعتبارسنجی هم وجود دارد.

اکنون قصد داریم یک کد جاوااسکریپت بنویسیم تا هم ارسال فرم را مدیریت کنیم و هم اعتبارسنجی سمت کلاینت را انجام دهیم:

const registrationForm = document.getElementById("registrationForm");
const errorMessages = document.getElementById("errorMessages");

registrationForm.addEventListener("submit", function (event) {
  event.preventDefault();

  const { username, email, password } = registrationForm.elements;

  errorMessages.innerHTML = "";

  if (!username.value.trim()) {
    displayError("Username is required.");
    return;
  }

  if (!email.value.trim() || !isValidEmail(email.value)) {
    displayError("Please enter a valid email address.");
    return;
  }

  if (!password.value.trim() || !isStrongPassword(password.value)) {
    displayError(
      "Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one digit, and one special character."
    );
    return;
  }

  alert("Registration successful!");
  registrationForm.reset();
});

function displayError(message) {
  errorMessages.innerHTML += `<div class="error">${message}</div>`;
}

function isValidEmail(email) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

function isStrongPassword(password) {
  return /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,}$/.test(password);
}

جاوااسکریپت Handling: فرم و container پیام خطا را با استفاده از getElementById انتخاب می‌کنیم. ما یک event listener را به submit event فرم پیوست می‌نماییم. هنگامی که فرم ارسال می‌شود، با استفاده از event.preventDefault() از رفتار پیش‌فرض آن جلوگیری می‌کنیم.

اعتبارسنجی فرم: ما مقادیر username، email و password را بازیابی می‌کنیم.

همینطور یک اعتبارسنجی ساده انجام می‌دهیم به این صورت که نام کاربری نباید خالی باشد، ایمیل باید با فرمت معتبر باشد، رمز عبور باید حداقل ۸ کاراکتر داشته باشد و حداقل یک حرف بزرگ، یک حرف کوچک، یک عدد و یک کاراکتر خاص را شامل شود.

مدیریت خطا: در صورت عدم موفقیت در اعتبارسنجی، پیام خطای مربوطه در div errorMessages نمایش داده می‌شود.

Form Reset: پس از موفقیت‌آمیز بودن ثبت‌نام، که آن را با یک alert ساده نمایش می‌دهیم، فرم را با استفاده از registrationForm.reset() ریست می‌کنیم.

به طور کلی این مثال ایجاد فرم، مدیریت فرم با جاوااسکریپت، اعتبارسنجی فرم با استفاده از regular expressionها و نمایش پیام خطای سفارشی داینامیک را پوشش می‌دهد.

Radio Buttonها

Radio buttonها یکی از المنت‌های فرم رایج هستند که برای انتخاب یک گزینه از مجموعه‌ای از گزینه‌ها مورد استفاده قرار می‌گیرند. در جاوااسکریپت، می‌توانیم Radio buttonها را برای بازیابی انتخاب‌های کاربر و انجام اقدامات بر اساس آن انتخاب‌ها استفاده کنیم.

نحوه ساخت Radio Buttonها

ما زمانی که می‌خواهیم کاربر از بین گزینه‌های موجود، فقط یک مورد را انتخاب کند می‌توانیم از Radio buttonها استفاده کنیم.

می‌توانیم با استفاده از المنت <input> همراه با ویژگی type که بر روی "radio" تنظیم شده است، Radio buttonها را در HTML ایجاد کنیم. گروهی از Radio buttonها با ویژگی name یکسان، یک گروه radio را تشکیل می‌دهند. مثلا:

<!DOCTYPE html>
<html>
  <body>
    <form id="languageForm">
      <p>Select your favorite programming language:</p>
      <div>
        <input type="radio" name="language" value="JavaScript" id="js" />
        <label for="js">JavaScript</label>
      </div>
      <div>
        <input type="radio" name="language" value="Python" id="python" />
        <label for="python">Python</label>
      </div>
      <div>
        <input type="radio" name="language" value="Java" id="java" />
        <label for="java">Java</label>
      </div>
      <!-- More language options can be added here -->
    </form>
  </body>
</html>

ما از ویژگی‌های id و for برای دسترسی استفاده می‌کنیم و label را به Radio button مربوطه، مرتبط می‌کنیم.

نحوه بازیابی مقدار انتخاب شده از Radio Button

اکنون قصد داریم تا درمورد چگونگی بازیابی مقدار Radio button انتخاب شده با استفاده از جاوااسکریپت بحث کنیم.

<!-- HTML -->
   <button id="btn">Show Selected Language</button>
   <p id="output"></p>

   <script>
     const btn = document.querySelector("#btn");
     const radioButtons = document.querySelectorAll('input[name="language"]');
     const output = document.getElementById("output");

     btn.addEventListener("click", () => {
       let selectedLanguage;
       for (const radioButton of radioButtons) {
         if (radioButton.checked) {
           selectedLanguage = radioButton.value;
           break;
         }
       }
       // Displaying the output:
       output.innerText = selectedLanguage
         ? `You selected ${selectedLanguage}`
         : `You haven't selected any language`;
     });
   </script>

روش کارکرد کد بالا به این صورت است که:

کد جاوااسکریپت با انتخاب دکمه، radio buttonها و المنت‌های output از HTML document مقداردهی اولیه می‌شود. ما یک event listener کلیک را به المنت دکمه اضافه می‌کنیم. هنگامی که بر روی دکمه کلیک می‌شود، تابع درون event listener اجرا می‌شود.

در داخل event listener کلیک، روی همه radio buttonها در مجموعه radioButtons تکرار می‌کنیم. ما بررسی می‌کنیم که آیا یک radio button با استفاده از ویژگی checked آن انتخاب شده است یا خیر. اگر یک radio button تیک خورده باشد، مقدار آن را به متغیر selectedLanguage اختصاص می‌دهیم و با استفاده از break از حلقه خارج می‌شویم.

ما محتوای المنت output، یعنی تگ <p> با id output را بر اساس زبانی که انتخاب شده است به‌روزرسانی می‌کنیم. اگر یک زبان برنامه نویسی توسط کاربر انتخاب شده باشد، به این صورت که selectedLanguage true باشد، پیامی را به کاربر نشان می‌دهیم که زبان انتخاب شده را به نمایش می‌گذارد. در غیر این صورت از کاربر می‌خواهیم تا یک زبان را انتخاب کند.

رویداد change در Radio Button

هنگامی که یک radio button تیک می‌خورد یا تیک آن برداشته می‌شود، یک رویداد change را اجرا می‌کند. ما می‌توانیم با استفاده از addEventListener() این event را بررسی کنیم. در event handler، می‌توانیم با استفاده از this.checked و this.value به state و value مربوط به radio buttonای که تیک خورده است، دسترسی داشته باشیم.

radioButton.addEventListener('change', function (e) {
  if (this.checked) {
    console.log(this.value);
  }
});

نحوه ساخت Radio Buttonهای داینامیک

اکنون قصد داریم تا نحوه ساخت radio button به صورت داینامیک با استفاده از جاوااسکریپت را باهم بررسی کنیم. این موضوع زمانی مفید است که می‌خواهیم گزینه‌های radio button را به صورت داینامیک و بر اساس معیارها یا داده‌های خاصی ایجاد کنیم.

فرض کنید یک آرایه از زبان‌های برنامه نویسی داریم و می‌خواهیم radio buttonها را به صورت داینامیک برای هر گزینه زبان ایجاد نماییم:

<!DOCTYPE html>
<html>
  <body>
    <div id="languages"></div>

    <script>
      const languageOptions = ["Python", "Javascript", "C++", "Java"];

      // Generate the radio buttons
      const languages = document.querySelector("#languages");
      languages.innerHTML = languageOptions.map((language) => `
          <div>
              <input type="radio" name="language" value="${language}" id="${language}">
              <label for="${language}">${language}</label>
          </div>`).join(' ');
    </script>
  </body>
</html>

این کد، radio buttonها را به صورت داینامیک و بر اساس آرایه languageOptions تولید کرده و آن‌ها را در المنت container، یعنی<div id="languages"></div> وارد می‌کند. هر radio button دارای ID و value منحصربه‌فرد مربوط به نام زبان است و labelها با استفاده از ویژگی for به radio buttonهای مربوطه مرتبط می‌شوند.

پس از ایجاد داینامیک radio buttonها در فرم HTML، اکنون event listenerهای change را به آن‌ها اضافه می‌کنیم تا بتوانیم با استفاده از جاوااسکریپت، تغییرات در انتخاب را مدیریت کنیم.

 <!-- HTML -->
    <div id="languages"></div>
    <div id="languageOutput"></div> // we create this one to fetch our selected language output
    
    <!-- Generate the radio buttons -->

// Attaching Change Event Listeners
const radioButtons = document.querySelectorAll('input[name="language"]');
for (const radioButton of radioButtons) {
    radioButton.addEventListener('change', showSelectedlanguage);
}        

// Handling the Change Event
function showSelectedlanguage() {
    if (this.checked) {
        document.querySelector('#languageOutput').innerText = `You selected ${this.value}`;
    }
}

کاری که قطعه کد بالا انجام می‌دهد به صورت زیر می‌باشد:

Checkboxeها

نحوه ساخت یک Checkbox در HTML

ابتدا یک checkbox با استفاده از المنت <input> می‌سازیم و ویژگی type آن را که روی "checkbox" تنظیم می‌کنیم.

<label for="agree">
   <input type="checkbox" id="agree" name="agree" value="yes"> I agree to the terms
</label>

نحوه بررسی Checkbox علامت‌گذاری شده

یک checkbox در HTML می‌تواند دو حالت داشته باشد: علامت زده و بدون علامت. ما می‌توانیم با استفاده از ویژگی checked مشخص کنیم که کدام حالت فعال است. اگر true باشد، checkbox تیک می‌خورد، در غیر این صورت تیک آن برداشته می‌شود. مثلا:

<!DOCTYPE html>
<html>
<body>
    <label for="agree">
        <input type="checkbox" id="agree" name="agree"> I agree to the terms
    </label>

    <script>
        const checkbox = document.getElementById('agree');
        console.log(checkbox.checked);
    </script>
</body>
</html>

نحوه دریافت مقادیر Checkbox

در فرم‌های HTML، زمانی که یک checkbox تیک می‌خورد و در فرم ارسال می‌گردد، مرورگر در داده‌های فرم شامل یک checkbox می‌شود که ویژگی name آن به عنوان key و ویژگی value، در صورت وجود، به عنوان value در نظر گرفته می‌شود. اما اگر علامت checkbox را برداریم، اصلاً در داده‌های فرم گنجانده نمی‌شود.

<label for="agree">
    <input type="checkbox" id="agree" name="agree"> I agree to the terms
</label>

<button id="btn">Show Value</button>
<script>
    const checkbox = document.querySelector('#agree');
    const btn = document.querySelector('#btn');
    btn.onclick = () => {
       alert(checkbox.value);
    };
</script>

بنابراین نکته‌ای که وجود دارد این است، هنگامی که یک checkbox تیک خورده و در فرم ارسال‌شده گنجانده می‌شود، اگر هیچ ویژگی value به صراحت برای المنت ورودی checkbox تعریف نشده باشد، مرورگر به طور پیش‌فرض 'on' را به عنوان value ارسال می‌کند. هنگام مدیریت فرم، برای رسیدگی دقیق به وضعیت checkbox با استفاده از جاوااسکریپت، به جای استفاده از ویژگی value، از ویژگی checked استفاده می‌کنیم.

نحوه مدیریت Checkbox های چندگانه

گاهی اوقات، ممکن است لازم باشد با چندین checkbox تحت عنوان یک نام، کار کنیم و بخواهیم مقادیر checkboxهای انتخاب شده را بازیابی نماییم. به عنوان مثال:

<!DOCTYPE html>
<html>
  <body>
    <p>Select your preferred languages:</p>
    <label for="l1">
      <input type="checkbox" name="language" value="C++" id="l1" />C++
    </label>
    <label for="l2">
      <input type="checkbox" name="language" value="Python" id="l2" />Python
    </label>
    <label for="l3">
      <input type="checkbox" name="language" value="Java" id="l3" />Java
    </label>
    <p>
      <button id="btn">Get Selected Languages</button>
    </p>

    <script>
      const btn = document.querySelector("#btn");
      btn.addEventListener("click", () => {
        const checkboxes = document.querySelectorAll(
          'input[name="language"]:checked'
        );
        const selectedLanguages = Array.from(checkboxes).map(
          (checkbox) => checkbox.value
        );
        alert("Selected Languages: " + selectedLanguages.join(", "));
      });
    </script>
  </body>
</html>

در این مثال، ما checkboxهایی برای انتخاب زبان‌های برنامه نویسی که کاربران ترجیح می‌دهند از آن‌ها استفاده کنند را داریم.

نحوه Check و Uncheck کردن همه Checkboxeها

تابعی تعریف می‌کنیم تا بطور هم‌زمان همه checkboxها را تیک بزند یا تیک آن‌ها را بردارد:

<!DOCTYPE html>
<html>
  <body>
    <p>
      <button id="btn">Check / Uncheck All</button>
    </p>
    <p>Select your preferred languages:</p>
    <label for="l1">
      <input type="checkbox" name="language" value="C++" id="l1" />C++
    </label>
    <label for="l2">
      <input type="checkbox" name="language" value="Python" id="l2" />Python
    </label>
    <label for="l3">
      <input type="checkbox" name="language" value="Java" id="l3" />Java
    </label>
    <script src="script.js"></script>
  </body>
</html>

کد جاوااسکریپتی آن به صورت زیر است:

// function to check or uncheck all checkboxes
function check(checked = true) {
  const checkboxes = document.querySelectorAll('input[name="language"]');

  // Iterate through each checkbox
  checkboxes.forEach((checkbox) => {
    // Set the checked property of each checkbox to the value of the 'checked' parameter
    checkbox.checked = checked;
  });
}

// function to check all checkboxes and change button behavior to uncheck all
function checkAll() {
  check();
  this.onclick = uncheckAll;
}

// function to uncheck all checkboxes and change button behavior to check all
function uncheckAll() {
  check(false);
  this.onclick = checkAll;
}

const btn = document.querySelector("#btn");

btn.onclick = checkAll;

در این مثال، ما یک دکمه با عنوان Check / Uncheck All داریم.

رویکرد جایگزین می‌تواند به صورت زیر باشد:

function checkAll(checked = true) {
  const checkboxes = document.querySelectorAll('input[name="language"]');
  checkboxes.forEach((checkbox) => {
    checkbox.checked = checked;
  });
}

const btn = document.querySelector("#btn");

btn.addEventListener("click", () => {
  // Find the first checkbox with the name attribute set to 'language'
  const firstCheckbox = document.querySelector('input[name="language"]');
  // Check if the first checkbox is checked
  const isChecked = firstCheckbox.checked;
  // Call the checkAll function with the opposite state of the first checkbox
  checkAll(!isChecked);
});

در این مثال، اولین checkbox با name language را انتخاب می‌کنیم تا وضعیت علامت‌گذاری شده فعلی آن مشخص شود. سپس، checkAll() را با حالت مخالف آن فراخوانی می‌کنیم.

نحوه ساخت CheckBoxهای داینامیک

<!DOCTYPE html>
<html>
  <body>
    <div id="languages"></div>

    <script>
      const languageOptions = ["Python", "Javascript", "C++", "Java"];

      // Generate the checkboxes
      const html = languageOptions
        .map(
          (language) => `<label for="language-${language}">
                <input type="checkbox" name="language" id="language-${language}" value="${language}"> ${language}
            </label>`
        )
        .join(" ");
      document.querySelector("#languages").innerHTML = html;
    </script>
  </body>
</html>

کاری که این کد انجام می‌دهد این است که:

المنت Select

المنت <select> در HTML یک لیست dropdown از گزینه‌ها را برای کاربران فراهم می‌کند. کاربران می‌توانند یک یا چند گزینه را انتخاب کنند. به عنوان مثال:

<select id="cities">
    <option value="JAI">Jaipur</option>
    <option value="DEL">New Delhi</option>
    <option value="UDR">Udaipur</option>
    <option value="MUM">Mumbai</option>
</select>

به طور پیش‌فرض، المنت <select> امکان انتخاب یک مورد را فراهم می‌کند. برای این که بتوانیم چندین مورد را انتخاب کنیم باید ویژگی multiple را به آن اضافه نماییم.

<select id="cities" multiple>

در این مثال، کاربران اکنون می‌توانند با نگه داشتن کلید Ctrl در ویندوز و یا Cmd در Mac در حین کلیک کردن، چندین گزینه را انتخاب کنند.

نحوه تعامل با المنت Select

برای این که بتوانیم با استفاده از جاوااسکریپت با المنت <select> تعامل داشته باشیم، باید از تایپ HTMLSelectElement استفاده کنیم که ویژگی‌های مفیدی مانند selectedIndex و value را ارائه می‌کند. مثلا:

<script>
const selectElement = document.getElementById('cities');
console.log(selectElement.selectedIndex); // Returns the index of the selected option
console.log(selectElement.value); // Returns the value of the selected option
console.log(selectElement.multiple); // Returns true if multiple selections are allowed
</script>

جاوااسکریپت این امکان را به ما می‌دهد تا eventها را در المنت <select> مدیریت کنیم، مانند زمانی که کاربر یک گزینه را انتخاب می‌کند. به عنوان مثال:

<button id="btn">Get Selected City</button>
    <script>
      const btn = document.querySelector("#btn");
      const selectElement = document.getElementById("cities");
      btn.onclick = (event) => {
        event.preventDefault();
        const selectedCity =
          selectElement.options[selectElement.selectedIndex].text;
        alert(`Selected city: ${selectedCity}, 
        Index: ${selectElement.selectedIndex}`);
      };
    </script>

استفاده از ویژگی value: ویژگی value نشان دهنده مقدار گزینه انتخاب شده است. مثلا:

<select id="cities">
    <option value="">Jaipur</option> 
    <option value="DEL">New Delhi</option>
    <option value="UDR">Udaipur</option>
    <option>Mumbai</option>
</select>
const btn = document.querySelector("#btn");
const selectElement = document.querySelector("#cities");

btn.onclick = (event) => {
    event.preventDefault();
    alert(selectElement.value);
};

دسترسی به گزینه‌ها با استفاده از جاوااسکریپت

تایپ HTMLOptionElement المنت‌های <option> را در یک المنت <select> در جاوااسکریپت نشان می‌دهد و ویژگی‌هایی مانند index، selected، text و value را برای دسترسی به اطلاعات مربوط به هر گزینه فراهم می‌کند.

const selectElement = document.getElementById('cities');
const secondOptionText = selectElement.options[1].text; // Accessing text of the second option
const secondOptionValue = selectElement.options[1].value; // Accessing value of the second option

نحوه مدیریت انتخاب‌های چندگانه

هنگامی که یک المنت <select> امکان انتخاب‌های متعدد را فراهم می‌کند، می‌توانیم از طریق گزینه‌های آن تکرار کنیم تا ببینیم کدام یک انتخاب شده است و مقادیر متنی آن‌ها را بازیابی نماییم.

const selectElement = document.getElementById('cities');
const selectedOptions = Array.from(selectElement.options).filter(option => option.selected);
const selectedValues = selectedOptions.map(option => option.text);

خروجی، یک آرایه حاوی متنی از گزینه‌های انتخاب شده خواهد بود. به جای آن می‌توانیم از option.value برای بدست آوردن آرایه‌ای از مقادیر استفاده کنیم. به عنوان مثال:

<!DOCTYPE html>
<html>
  <body>
    <select id="cities" multiple>
      <option value="JAI">Jaipur</option>
      <option value="DEL">New Delhi</option>
      <option value="UDR">Udaipur</option>
      <option value="MUM">Mumbai</option>
    </select>

    <button id="btn">Get Selected Cities</button>
    <script>
      const btn = document.querySelector("#btn");
      const selectElement = document.querySelector("#cities");

      btn.onclick = (event) => {
        event.preventDefault();
        const selectedOptions = Array.from(selectElement.options)
          .filter((option) => option.selected)
          .map((option) => option.text);
        alert("Selected City: " + selectedOptions.join(", "));
      };
    </script>
  </body>
</html>

بررسی تفاوت‌های بین Change Event و Input Event

input event در جاوااسکریپت هر زمان که مقدار یک المنت input، <select> یا <textarea> تغییر کند فعال می‌شود. برخلاف change event، که منتظر می‌ماند تا یک مقدار commit شود. به عنوان مثال زمانی که یک input از حالت focus خارج می‌شود، اما input event به طور مداوم با تغییر مقدار فعال می‌شود.

به طور کلی input event راهی برای پاسخگویی به مقادیر input کاربر به صورت real-time فراهم می‌کند. مثلا:

<!DOCTYPE html>
<html>
<body>
    <label for="userInput">Enter Your Name:</label>
    <input type="text" id="userInput" placeholder="Your name">
    <p>Your name is: <span id="displayName"></span></p>
</body>
</html>

این کد HTML یک صفحه وب ساده با یک فیلد ورودی برای کاربر ایجاد می‌کند تا نام خود را وارد کند. همینطور یک المنت پاراگراف دارد که در آن نام وارد شده را به صورت داینامیک نمایش می‌دهیم.

<script>
    const userInput = document.getElementById('userInput');
    const Name = document.getElementById('displayName');

    userInput.addEventListener('input', function() {
        Name.textContent = userInput.value || 'Guest!';
    });
</script>

جمع‌بندی

با درک اصول المنت‌ها، ویژگی‌ها و eventهای فرم HTML، می‌توانیم فرم‌های وب داینامیک و کاربر پسند بسازیم که تجربه کاربری را بهبود می‌بخشد. همینطور جاوااسکریپت نقش بسیار مهمی را در رسیدگی به ارسال و مدیریت فرم، اعتبارسنجی داده‌هایی که کاربر وارد می‌کند و ارائه بازخورد real-time به کاربران ایفا می‌کند.

در این مقاله سعی کردیم تا با بررسی مثل‌های عملی با روش کار radio buttonها، checkboxها، المنت‌های select و مدیریت انتخاب‌های چندگانه بیشتر آشنا شویم.