107- آموزش جاوااسکریپت | پروژه عملی قسمت 8 از 8: پیادهسازی ویرایش پستها و مدیریت حالت فرم در پروژه Micro Posts
در این آموزش، قابلیت ویرایش پستها را در پروژه Micro Posts پیادهسازی میکنیم. ابتدا فرم را وارد حالت ویرایش میکنیم، اطلاعات پست را داخل فیلدها قرار میدهیم، دکمه لغو میسازیم و در نهایت با درخواست PUT پست را بهروزرسانی میکنیم.
تا اینجا در پروژه Micro Posts عملیات ایجاد، نمایش و حذف پستها را پیادهسازی کردهایم. حالا نوبت به بخش ویرایش میرسد. برای این کار باید ابتدا اطلاعات پست انتخابشده را داخل فرم قرار دهیم، ظاهر فرم را به حالت ویرایش تغییر دهیم و سپس دادههای جدید را با درخواست PUT به API ارسال کنیم.
فعالسازی حالت ویرایش
وقتی کاربر روی آیکن ویرایش کلیک میکند، هنوز عملیات بهروزرسانی انجام نمیشود. در این مرحله فقط باید فرم را وارد حالت ویرایش کنیم. یعنی:
- عنوان و متن پست داخل فرم قرار بگیرد
- مقدار
idدر فیلد مخفی ذخیره شود - متن و رنگ دکمه ارسال تغییر کند
- یک دکمه برای لغو ویرایش نمایش داده شود
برای این کار در فایل app.js یک رویداد click روی بخش #posts ثبت میکنیم:
document.querySelector("#posts").addEventListener("click", enableEdit);
دریافت اطلاعات پست انتخابشده
از آنجا که دکمههای ویرایش بهصورت پویا ساخته میشوند، باید از event delegation استفاده کنیم. همچنین چون کلیک روی آیکن داخل لینک انجام میشود، باید parentElement را بررسی کنیم.
function enableEdit(e) {
e.preventDefault();
if (e.target.parentElement.classList.contains("edit")) {
const id = e.target.parentElement.dataset.id;
const body =
e.target.parentElement.previousElementSibling.textContent;
const title =
e.target.parentElement.previousElementSibling.previousElementSibling.textContent;
const data = {
id,
title,
body
};
ui.fillForm(data);
}
}
در این کد:
- شناسه پست از
data-idگرفته میشود - متن پست با استفاده از
previousElementSiblingاز DOM استخراج میشود - اطلاعات پست در قالب یک آبجکت به متد
fillFormارسال میشود
قرار دادن اطلاعات پست داخل فرم
حالا در فایل ui.js متدی میسازیم تا فرم را با اطلاعات پست پر کند:
fillForm(data) {
this.titleInput.value = data.title;
this.bodyInput.value = data.body;
this.idInput.value = data.id;
this.changeFormState("edit");
}
این متد سه کار انجام میدهد:
- مقدار عنوان را در فیلد عنوان قرار میدهد
- مقدار متن را در فیلد متن قرار میدهد
- شناسه پست را در فیلد مخفی ذخیره میکند
سپس متد changeFormState("edit") را فراخوانی میکند تا فرم وارد حالت ویرایش شود.
تغییر ظاهر فرم در حالت ویرایش
برای مدیریت وضعیت فرم، یک متد به نام changeFormState میسازیم. اگر فرم در حالت ویرایش باشد، متن و کلاس دکمه ارسال تغییر میکند و دکمه لغو ویرایش نمایش داده میشود.
changeFormState(type) {
if (type === "edit") {
this.postSubmit.textContent = "Update Post";
this.postSubmit.className = "post-submit btn btn-warning btn-block";
const button = document.createElement("button");
button.className = "post-cancel btn btn-light btn-block";
button.appendChild(document.createTextNode("Cancel Edit"));
const cardForm = document.querySelector(".card-form");
const formEnd = document.querySelector(".form-end");
cardForm.insertBefore(button, formEnd);
} else {
this.postSubmit.textContent = "Post It";
this.postSubmit.className = "post-submit btn btn-primary btn-block";
if (document.querySelector(".post-cancel")) {
document.querySelector(".post-cancel").remove();
}
this.clearIdInput();
this.clearFields();
}
}
در اینجا:
- دکمه اصلی از حالت افزودن به حالت ویرایش تغییر میکند
- دکمه
Cancel Editبهصورت پویا ساخته میشود - اگر فرم به حالت عادی بازگردد، دکمه لغو حذف میشود و فرم پاکسازی میشود
پاک کردن فیلد شناسه
برای بازگرداندن فرم به حالت افزودن، باید مقدار فیلد مخفی id را نیز پاک کنیم. برای این کار یک متد ساده میسازیم:
clearIdInput() {
this.idInput.value = "";
}
اعتبارسنجی فرم قبل از ارسال
قبل از ثبت یا ویرایش پست، بهتر است بررسی کنیم که فیلدهای عنوان و متن خالی نباشند:
function submitPost() {
const title = document.querySelector("#title").value;
const body = document.querySelector("#body").value;
const id = document.querySelector("#id").value;
const data = {
title,
body
};
if (title === "" || body === "") {
ui.showAlert("Please fill in all fields", "alert alert-danger");
} else {
// create or update
}
}
با این کار اگر یکی از فیلدها خالی باشد، پیام خطا نمایش داده میشود.
لغو حالت ویرایش
برای اینکه کاربر بتواند از حالت ویرایش خارج شود، باید روی دکمه Cancel Edit رویداد ثبت کنیم. چون این دکمه بهصورت پویا ساخته میشود، باز هم از event delegation استفاده میکنیم.
document.querySelector(".card-form").addEventListener("click", cancelEdit);
سپس تابع مربوط به آن را مینویسیم:
function cancelEdit(e) {
if (e.target.classList.contains("post-cancel")) {
ui.changeFormState("add");
}
e.preventDefault();
}
با این کار، فرم دوباره به حالت افزودن بازمیگردد.
تشخیص حالت افزودن یا ویرایش
در تابع submitPost باید مشخص کنیم که کاربر در حال افزودن پست جدید است یا ویرایش پست موجود. معیار این تشخیص، وجود مقدار در فیلد مخفی id است:
- اگر
idخالی باشد، باید پست جدید ایجاد شود - اگر
idمقدار داشته باشد، باید پست موجود بهروزرسانی شود
ثبت پست جدید یا بهروزرسانی پست موجود
کد نهایی تابع submitPost به این صورت خواهد بود:
function submitPost() {
const title = document.querySelector("#title").value;
const body = document.querySelector("#body").value;
const id = document.querySelector("#id").value;
const data = {
title,
body
};
if (title === "" || body === "") {
ui.showAlert("Please fill in all fields", "alert alert-danger");
} else {
if (id === "") {
http
.post("http://localhost:3000/posts", data)
.then(data => {
ui.showAlert("Post Added", "alert alert-success");
ui.clearFields();
getPosts();
})
.catch(err => console.log(err));
} else {
http
.put(`http://localhost:3000/posts/${id}`, data)
.then(data => {
ui.showAlert("Post Updated", "alert alert-success");
ui.changeFormState("add");
getPosts();
})
.catch(err => console.log(err));
}
}
}
در این پیادهسازی:
- اگر
idخالی باشد، از متدpostاستفاده میکنیم - اگر
idمقدار داشته باشد، از متدputاستفاده میکنیم - بعد از ویرایش موفق، فرم به حالت افزودن برمیگردد
- فهرست پستها دوباره از API دریافت میشود
جمعبندی ساختار ویرایش پست
در این بخش، مهمترین قسمت پروژه یعنی ویرایش پستها را کامل کردیم. روند کار به این صورت است:
- کاربر روی دکمه ویرایش کلیک میکند
- اطلاعات پست از DOM خوانده میشود
- فرم با دادههای پست پر میشود
- فرم وارد حالت ویرایش میشود
- در زمان ارسال فرم، اگر
idوجود داشته باشد درخواستPUTارسال میشود - پس از ویرایش، فرم به حالت اولیه بازمیگردد
آمادهسازی نسخه نهایی پروژه
بعد از کامل شدن پروژه، میتوانید فایلهای نهایی را برای استفاده در محیط واقعی build کنید:
npm run build
این دستور تمام ماژولهای جاوااسکریپت را در فایل نهایی bundle میکند. برای استقرار سمت فرانتاند معمولا این بخشها کافی هستند:
- فایل
index.html - پوشه
assets - پوشه
build
اگر پروژه به API واقعی متصل باشد، بخش بکاند باید جداگانه روی یک سرور یا سرویس ابری اجرا شود.