برنامه Microposts: اضافه کردن پست‌ها و نمایش Alert

Microposts Application: Adding Posts and Displaying Alert

11 شهریور 1399
برنامه ی microposts: اضافه کردن پست ها و نمایش alert

در قسمت قبل با موفقیت پست ها را دریافت کرده و سپس آن ها را در UI نمایش دادیم اما هنوز قابلیت اضافه کردن پست ها را پیاده سازی نکرده ایم که کار این قسمت است. از آنجایی که فقط یک فرم ساده برای اضافه کردن پست ها داریم، پیاده سازی آن اصلا سخت نیست بلکه با یک event-listener قابل انجام است:

// Get posts on DOM load
document.addEventListener('DOMContentLoaded', getPosts);

// Listen for add post
document.querySelector('.post-submit').addEventListener('click', submitPost);

یعنی زمانی که کاربر روی دکمه ثبت پست کلیک کند باید تابعی به نام submitPost اجرا شود. این تابع تعریف نشده است بنابراین شروع به تعریف آن می کنیم:

// Submit Post
function submitPost() {

}

ما باید درون این تابع کدهایی بنویسیم که ابتدا مقادیر تایپ شده درون فرم را دریافت کنیم و سپس با استفاده از ماژول http (که در جلسات قبل نوشتیم) یک درخواست POST را برای ثبت این داده ها ارسال کنیم. بنابراین:

// Submit Post
function submitPost() {
  const title = document.querySelector('#title').value;
  const body = document.querySelector('#body').value;
}

اگر از جلسات قبل یادتان باشد ماژول http اطلاعات دلخواه ما را در قالب body به URL مشخص شده ارسال می کرد بنابراین این اطلاعات دریافتی را در قالب یک شیء به نام data قرار می دهیم:

// Submit Post
function submitPost() {
  const title = document.querySelector('#title').value;
  const body = document.querySelector('#body').value;

  const data = {
    title,
    body
  }
}

نکته: در نسخه ES6 به بعد جاوا اسکریپت، اگر نام خصوصیت با مقدار آن خصوصیت یکی باشد می توانیم به روش بالا آن را خلاصه نویسی کنیم. روش قدیمی نوشتن همین شیء را کد زیر مشاهده می کنید:

  const data = {
    title: title,
    body: body
  }

در نهایت نیز درخواست POST خودمان را می نویسیم:

// Submit Post
function submitPost() {
  const title = document.querySelector('#title').value;
  const body = document.querySelector('#body').value;

  const data = {
    title,
    body
  }

  // Create Post
  http.post('http://localhost:3000/posts', data)
    .then(data => {
      getPosts();
    })
    .catch(err => console.log(err));
}

آدرس URL این درخواست را از سرور مجازی خود گرفته ایم (اگر نمی دانید، به جلسات قبل مراجعه کنید) و پارامتر دوم post نیز همان body ما می باشد. با این کار یک promise دریافت می کنیم بنابراین باید از then برای دریافت پاسخ و catch برای دریافت خطاها استفاده کنیم. پس از اینکه پاسخ را دریافت کردیم باید getPosts را یک بار صدا بزنیم تا دوباره پست های ما را دریافت کرده و در UI نمایش دهد در غیر این صورت پست جدیدمان را نخواهیم دید. در صورتی که به خطا برخورد کنیم نیز آن را log می کنیم. در حال حاضر برنامه ما بدون نقص کار می کند اما از نظر UX خیلی خوب طراحی نشده است چرا که کاربر نمی داند چه زمانی پست هایش اضافه شده اند مگر آنکه به پایین صفحه رفته و خودش پست ها را چک کند.

برای حل این مسئله می توانیم یک alert نشان دهیم که به کاربر بگوید پست های او با موفقیت اضافه شده اند. البته مشکل دیگری نیز داریم. پس از اضافه شدن پست، title و توضیحات آن از فیلدها پاک نمی شوند که بسیار زشت است بنابراین تابعی هم برای این کار نیاز داریم بنابراین:

  // Create Post
  http.post('http://localhost:3000/posts', data)
    .then(data => {
      ui.showAlert('Post added', 'alert alert-success');
      ui.clearFields();
      getPosts();
    })
    .catch(err => console.log(err));

یعنی دو تابع showAlert و getPosts را باید تعریف کنیم تا اولا پیامی به کاربر بدهند که پست هایش اضافه شده اند و دوما فیلدها را پس از ثبت پست پاک کنند. در ضمن پارامتر دوم متد showAlert قرار است کلاس هایی باشد که به این alert اضافه خواهند شد. برای این کار وارد فایل ui.js شوید. حالا پس از متد showPosts متد مورد نظر خودمان را تعریف می کنیم:

  showAlert(message, className) {
    this.clearAlert();

    // Create div
    const div = document.createElement('div');
    // Add classes
    div.className = className;
    // Add text
    div.appendChild(document.createTextNode(message));
    // Get parent
    const container = document.querySelector('.postsContainer');
    // Get posts
    const posts = document.querySelector('#posts');
    // Insert alert div
    container.insertBefore(div, posts);

    // Timeout
    setTimeout(() => {
      this.clearAlert();
    }, 3000);
  }

در این متد ابتدا یک بار متد ClearAlert را صدا می زنیم که کارش پاک کردن alert است (هنوز آن را تعریف نکرده ایم) سپس یک div جدید به همراه متن و کلاسش را ساخته و در نهایت با استفاده از تابع setTimeout پس از سه ثانیه دوباره clearAlert را صدا می زنیم تا aler ما پاک شود. منطق این کد بسیار ساده است و اگر تا این قسمت از این سری آموزشی جلو آمده باشید حتما متوجه آن خواهید شد اما من به صورت خلاصه آن را توضیح می دهم:

  • ابتدا یک div می سازیم.
  • سپس کلاس های دریافتی (پارامتر دوم) را به آن اضافه می کنیم.
  • سپس با استفاده از createTextNode متن پیام را به آن اضافه کرده ایم.
  • سپس نگهدارنده (تگ پدر) هدف را می گیریم (جایی که باید پیام را در آن وارد کنیم).
  • سپس نگهدارنده (تگ پدر) پست ها را گرفته ایم تا پیام خود را دقیقا قبل از آن ها وارد کنیم.
  • نهایتا با استفاده از متد insertBefore کار خود را تمام کرده و پیام را نمایش می دهیم.

در مرحله بعدی تابع ClearAlert را تعریف می کنیم:

  clearAlert() {
    const currentAlert = document.querySelector('.alert');

    if(currentAlert) {
      currentAlert.remove();
    }
  }

در این متد نیز ابتدا سعی می کنیم عنصری با کلاس alert را بگیریم. اگر وجود داشت یعنی دارای alert هستیم و باید آن را remove کنیم در غیر این صورت نیز یعنی Alert ای نداریم و کاری نمی کنیم. در نهایت تابع clearFields را نیز صدا می زنیم:

  clearFields() {
    this.titleInput.value = '';
    this.bodyInput.value = '';
  }

با این کار این قسمت نیز تکمیل شده است و برنامه ما به خوبی کار می کند. شما می توانید این کدها را خودتان در مرورگر خود تست کنید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری پروژه‌های مدرن جاوا اسکریپت توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.