در قسمت قبل با موفقیت پست ها را دریافت کرده و سپس آن ها را در 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 ما پاک شود. منطق این کد بسیار ساده است و اگر تا این قسمت از این سری آموزشی جلو آمده باشید حتما متوجه آن خواهید شد اما من به صورت خلاصه آن را توضیح می دهم:
در مرحله بعدی تابع ClearAlert را تعریف می کنیم:
clearAlert() { const currentAlert = document.querySelector('.alert'); if(currentAlert) { currentAlert.remove(); } }
در این متد نیز ابتدا سعی می کنیم عنصری با کلاس alert را بگیریم. اگر وجود داشت یعنی دارای alert هستیم و باید آن را remove کنیم در غیر این صورت نیز یعنی Alert ای نداریم و کاری نمی کنیم. در نهایت تابع clearFields را نیز صدا می زنیم:
clearFields() { this.titleInput.value = ''; this.bodyInput.value = ''; }
با این کار این قسمت نیز تکمیل شده است و برنامه ما به خوبی کار می کند. شما می توانید این کدها را خودتان در مرورگر خود تست کنید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.